/*
Cipher.java
This program encodes and decodes text strings using a cipher that
can be specified by the user.
*/
import java.io.*;
public class Cipher
{
public static void printID()
{
// output program ID
System.out.println ("*********************");
System.out.println ("* Cipher *");
System.out.println ("* *");
System.out.println ("* *");
System.out.println ("* *");
System.out.println ("* CS 181-03 *");
System.out.println ("*********************");
}
public static void printMenu()
{
// output menu
System.out.println("\n\n****************************" +
"\n* 1. Set cipher code. *" +
"\n* 2. Encode text. *" +
"\n* 3. Decode coded text. *" +
"\n* 4. Exit the program *" +
"\n****************************");
}
public static String getText(BufferedReader input, String prompt)
throws IOException
{
// prompt the user and get their response
System.out.print(prompt);
return input.readLine();
}
public static int getInteger(BufferedReader input, String prompt)
throws IOException
{
// prompt and get response from user
String text = getText(input, prompt);
// convert it to an integer
return (new Integer(text).intValue());
}
public static String encode(String original, int offset)
{
// declare constants
final int ALPHABET_SIZE = 26; // used to wrap around A-Z
String encoded = ""; // base for string to return
char letter; // letter being processed
// convert message to upper case
original = original.toUpperCase();
// process each character of the message
for (int index = 0; index < original.length(); index++)
{
// get the letter and determine whether or not to
// add the cipher value
letter = original.charAt(index);
if (letter >='A' && letter <= 'Z')
{
// is A-Z, so add offset
// determine whether result will be out of A-Z range
if ((letter + offset) > 'Z') // need to wrap around to 'A'
letter = (char)(letter - ALPHABET_SIZE + offset);
else
if ((letter + offset) < ') // need to wrap around to 'Z'
letter = (char)(letter + ALPHABET_SIZE + offset);
else
letter = (char) (letter + offset);
}
// build encoded message string
encoded = encoded + letter;
}
return encoded;
}
public static String decode(String original, int offset)
{
// declare constants
final int ALPHABET_SIZE = 26; // used to wrap around A-Z
String decoded = ""; // base for string to return
char letter; // letter being processed
// make original message upper case
original = original.toUpperCase();
// process each letter of message
for (int index = 0; index < original.length(); index++)
{
// get letter and determine whether to subtract cipher value
letter = original.charAt(index);
if (letter >= 'A' && letter <= 'Z')
{
// is A-Z, so subtract cipher value
// determine whether result will be out of A-Z range
if ((letter - offset) < 'A') // wrap around to 'Z'
letter = (char)(letter + ALPHABET_SIZE - offset);
else
if ((letter - offset) > 'Z') // wrap around to 'A'
letter = (char)(letter - ALPHABET_SIZE - offset);
else
letter = (char) (letter - offset);
}
// build decoded message
decoded = decoded + letter;
}
return decoded;
}
// main controls flow throughout the program, presenting a
// menu of options the user.
public static void main (String[] args) throws IOException
{
// declare constants
final String PROMPT_CHOICE = "Enter your choice: ";
final String PROMPT_VALID = "\nYou must enter a number between 1" +
" and 4 to indicate your selection.\n";
final String PROMPT_CIPHER = "\nEnter the offset value for a caesar " +
"cipher: ";
final String PROMPT_ENCODE = "\nEnter the text to encode: ";
final String PROMPT_DECODE = "\nEnter the text to decode: ";
final String SET_STR = "1"; // selection of 1 at main menu
final String ENCODE_STR = "2"; // selection of 2 at main menu
final String DECODE_STR = "3"; // selection of 3 at main menu
final String EXIT_STR = "4"; // selection of 4 at main menu
final int SET = 1; // menu choice 1
final int ENCODE = 2; // menu choice 2
final int DECODE =3; // menu choice 4
final int EXIT = 4; // menu choice 3
final int ALPHABET_SIZE = 26; // number of elements in alphabet
// declare variables
boolean finished = false; // whether or not to exit program
String text; // input string read from keyboard
int choice; // menu choice selected
int offset = 0; // caesar cipher offset
// declare and instantiate input objects
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader input = new BufferedReader(reader);
// Display program identification
printID();
// until the user selects the exit option, display the menu
// and respond to the choice
do
{
// Display menu of options
printMenu();
// Prompt user for an option and read input
text = getText(input, PROMPT_CHOICE);
// While selection is not valid, prompt for correct info
while (!text.equals(SET_STR) && !text.equals(ENCODE_STR) &&
!text.equals(EXIT_STR) && !text.equals(DECODE_STR))
{
text = getText(input, PROMPT_VALID + PROMPT_CHOICE);
}
// convert choice to an integer
choice = new Integer(text).intValue();
// respond to the choice selected
switch(choice)
{
case SET:
// get the cipher value from the user and constrain to
// -25..0..25
offset = getInteger(input, PROMPT_CIPHER);
offset %= ALPHABET_SIZE;
break;
case ENCODE:
// get message to encode from user, and encode it using
// the current cipher value
text = getText(input, PROMPT_ENCODE);
text = encode(text, offset);
System.out.println("Encoded text is: " + text);
break;
case DECODE:
// get message to decode from user, and decode it using
// the current cipher value
text = getText(input, PROMPT_DECODE);
text = decode(text, offset);
System.out.println("Decoded text is: " + text);
break;
case EXIT:
// set exit flag to true
finished = true ;
break;
} // end of switch on choice
} while (!finished); // end of outer do loop
// Thank user
System.out.println("Thank you for using Cipher for all your" +
" code breaking and code making needs.");
}
}