Assignment 7: Creating a "Secret Code"
Fall 2006, David Matuszek

Purposes of this assignment:

General idea of the assignment:

I will provide a class SecretCode which contains a main method. When the main method is executed, it displays a window similar to the one at the right. Clicking the buttons will call methods in your code.

You will provide a class named CodeMachine which has methods in it to create a new "secret code" and to encode and decode secret messages.

Supplied code: SecretCode.java and a starter version of CodeMachine.java.

Details:

Write a class CodeMachine with (at least) the following methods:

public String createNewCode()
Creates a new "secret code." This is just a simple substitution code, such as a -> m, b -> y, c -> h, etc. No letter should substitute for itself; in other words, you can't have k -> k (for example). The method should save the newly created secret code in an instance variable or variables of the CodeMachine, and it should return a string containing the alphabet (in normal order), a newline ('\n'), and the alphabet (in scrambled order)--for example, "abcdefghijklmnopqrstuvwxyz\nehjkscdlmyznoapqrwtfguvibx".

public String encode(String input)
Using the input string, performs a letter-by-letter substitution, according to the secret code. Any character that isn't a letter should be unchanged. Case should be preserved; that is, capital letters are encoded as capital letters, and lowercase letters are encoded as lowercase letters.

public String decode(String input)
Using the input string, performs a letter-by-letter substitution, according to the secret code--but in the opposite direction from the encode method.

My SecretCode class expects to find the above methods, with the exact signatures specified, in your CodeMachine class; so these methods are required. The "helper" methods suggested below are only suggested, not required.

Use Test-Driven Development. Provide Javadoc comments and JUnit tests for all your CodeMachine methods.

Recommended approach:

To create a new "secret code," I suggest you create a char array of 26 locations, containing the lowercase letters of the alphabet. Every time you want a new secret code, just shuffle (randomize) this array.

To shuffle the array, I recommend writing a method void shuffle(char[] alphabet). You are already familiar with using Random, so this shouldn't be too hard.

Here are some facts that might come in handy:

To translate text, make a StringBuilder object from your input String. It's much easier to replace one character with another in a StringBuilder than in a String. Then, just go through character by character, doing the translation, and replacing each letter with its encoded (or decoded) counterpart. When you're done translating, use the toString() method to get a String back from the StringBuilder.

It's easier to look up characters in a String than in a char[]. Hence, you may wish to convert your char[] to a String.

Remember that the Character class has methods for converting letters to uppercase or to lowercase. It also has tests for whether a character is a letter, and if so, what case it is. If you can translate a single letter, and get the case right, you can get the case right for the entire text. Use the Java API, don't depend entirely on my lectures or your book.

I would suggest writing the following "helper" methods that you can call from encode and decode:

char translate(char ch, String fromAlphabet, String toAlphabet)
Translates a single character. If ch is lowercase, this method looks it up in the fromAlphabet, and returns the character in the corresponding location in the toAlphabet. If ch is uppercase, it does the approriate conversions to return the uppercase translation. If ch isn't a letter, it is just returned unchanged.

void translate(StringBuilder text, String fromAlphabet, String toAlphabet)
Using the previous method, translates all the characters in text.
These methods will encode or decode, depending on which order you give it the two alphabets. Or, you can use char[] parameters for the two alphabets, but that's probably a bit more work.

By the way--it isn't hard to test methods that return void, if they make changes in one of the supplied parameters. For example, the shuffle method described above changes the char[] array given as a parameter.

If you encode a string, and then decode it (without getting a new secret code), you should get back a string that is equal to the original string.

Also:

This is an individual project. You can talk with your classmates and help one another, but write and turn in your own code. Don't share code with anyone.

Remember to put your name in an @author tag in the Javadoc for your CodeMachine class.

Estimate how long this will take you. Write down your estimate. Keep track of how long it actually takes you. Put both numbers in the main Javadoc for your CodeMachine class.

Due date:

Thursday, October 26, before midnight. Via Blackboard.