|
C M S C 2 1 4 C o m p u t e r S c i e n c e I I S p r i n g 2 0 0 3 |
Project 2 is worth 9% of your grade.
This project deals with a circular doubly linked list containing a single alphabet that holds both plaintext and cipher character. It implements an Enigma machine.
Enigma Machine a German cipher machine consisting of 2 cipher
wheels that rotate each time a character is enciphered or deciphered. It
was used during WWII by the Germans for military and naval
communications.
Enigma
Machine
See the Enigma
Machine Work
Download an Enigma
Simulator
Please note that *all* programming projects in this course (including this one) are to be done independently or with the assistance of the instructional staff of this course only.
Please review the policies outlined on the class syllabus concerning the use of class computer accounts and concerning the University's Code of Academic Integrity. The instructors of this course will review the programs submitted by students for potential violations of the Code of Academic Integrity and if it is believed that a violation has occurred it will be referred to the Office of Judicial Programs and the Student Honor Council.
Hardcoding is considered a violation of academic integrity
You have implemented a Coder class that represents a wheel of letters for enciphering and deciphering in project 1. (If you haven't gotten this working yet, go back NOW and fix it!) Now you are ready to build a class called Enigma. When the Germans made their version of the Enigma, they had to keep a few things in mind; the machine had to be versatile and uncrackable.
VERSATILITY: Enigma machines were issued in mass to thousands of German vessels. Since the Germans could not allow the Allies (British and American forces) to read the encoded messages, it was necessary to make the Enigma machine versatile enough so that even if the Allies captured a vessel and acquired an Enigma machine, they still could not use it to decipher "coded" (enciphered) messages. To aid in versatility, we will implement the following characteristics in our Enigma class -- similar to what the Germans did:
With these allowances, it would be near impossible for an Ally to decipher a code even if she had an Enigma machine because she would not know if she had the right wheels, or which wheels to use.
I used the word "she" in the above paragraph because during World War II, women were heavily recruited into the Army (WAAC) and Navy (WAVES) to relieve men working in noncombat positions - many of which were in cryptography.
UNCRACKABILITY: Enciphered messages were sent using radio waves in Morse code, and unfortunately, anyone with a radio could intercept these messages. With the Allies on the alert, coded messages needed to be uncrackable. If you have ever worked on a cryptogram, you would know that there are two dead-giveaways in a code where each letter transcribes to one other letter.
Now that you understand what makes a good Enigma machine, you are ready to start the tasks. Read the entire section before starting because you might save yourself a lot of work and frustration if you understand the whole assignment first.
Since we are adding the functionality of spinning wheels, each wheel will be given a number that represents how many letters the wheel rotates for every enciphered character. This number will be called a cog.
When the wheel spins, the plaintext letters will be "off" from their original cipher letters by a certain amount. Rather than redirecting every pointer in the wheel, we can just keep track of how far "off" the letters are, and traverse down that extra amount. This number will be called offset. For example:
An example wheel (with offset = 3) before any rotationsNotice that the second wheel can be accomplished simply by using the first wheel, except once you find the plaintext letter, traverse one more letter in the DLL before grabbing the cipher letter. The case can be generalized for multiple turns of the wheel if 'offset' is augmented each time the wheel turns, and you traverse down your DLL 'offset' times. At this point, it should be evident why we needed to implement this as a doubly linked list -- since the wheels can turn in either direction, we may need to move left (counterclockwise) or right (clockwise) to grab the cipher letter. There is a complete example below.
Since we will be creating five wheels in our Enigma class, we can't have each wheel reading to the EOF, so this function will have to change. The reader method should read only the keyword and the position. Remember that the keyword can be any sequence of spaces and uppercase/lowercase alphabet characters. It is also possible that the keyword is the empty string. Each keyword is guaranteed to be followed by an integer between 0 and 25 inclusive, which is its offset. Refer to the BNF below.
Because of the way we have implemented our doubly linked list, we only have one copy of the alphabet. This makes deleting a letter such as 'Q' from a wheel rather complicated. Take a look at this example:
plaintext: d e f g h i j k l m n o p q r s t u v w x y z a b cNow if we delete the letter 'q' from our doubly linked list, 'v' will not have a cipher letter because we only have ONE copy of the alphabet, and 'q' is gone! To solve this problem, we will have the cipher letter of 'v' be 'j' -- that is, we will change the cipher-letter of the plaintext-letter that lost its cipher-letter to the cipher-letter that was pointed to by the deleted-letter.
plaintext: d e f g h i j k l m n o p r s t u v w x y z a b cNotice that now there are no 'q's in either line, and thus it is safe to have deleted 'q' completely.
HINTS:
Depending on how you write your code, the following situations may or may not need to be handled separately:
Let's say we wanted to encipher the message "go". First, encipher() would call augmentOffset() so that offset would increase by cog, so offset is now equal to 1. Then, encipher() would find plaintext 'g' on the original wheel and then call traverseOffset(), which would move curr left by offset (offset == 1) and then grab that cipher letter which is 'w'. For the second letter, encipher() would call augmentOffset() again so that offset would increase by cog, so offset is now equal to 2. Then, encipher() would find plaintext 'o' on the original wheel and then call traverseOffset(), which would move curr left by offset (offset == 2) and then grab that cipher letter which is 'e'.
As you can see from the wheel after one rotation, 'g' truly does transcribe to 'w', and looking at the wheel after two rotations, 'o' transcribes to 'e'.
To decipher the message "we", offset gets set to zero. When deciphering 'w', decipher() first calls augmentOffset() so that offset would increase by cog, so offset is now equal to 1. Then, decipher() would find cipherletter 'w' on the original wheel and then call traverseOffsetBackwards(), which would move curr right by offset (offset == 1) and then grab that plaintext letter which is 'g'. When deciphering 'e', decipher() would first call augmentOffset() so that offset would increase by cog, so offset is now equal to 2. Then, decipher() would find cipherletter 'e' on the original wheel and then call traverseOffsetBackwards(), which would move curr right by offset (offset == 2) and then grab that plaintext letter which is 'o'.
The explanations in the header file should be enough for you to accomplish this.
| See the class syllabus for policies concerning email
Last Modified: Saturday, February 20, 2003 |
|
|
|
|
|