From antiquity, people have worried about how to communicate private information to others without revealing, to adversaries, the content of their communications. The Allied forces in World War II, for example, used Navajo Indians for field communications because the enemy did not speak or understand the language of the Navajo. Also, when the Allied forces were able to steal Germany's Enigma machine, used for encrypting messages, the secret was so valued that English citizens were not notified of imminent bombing raids, lest Germany infer that its code had been broken. And today, internet commerce has brought the issue of secure transmission of private data to all our lives.
For this assignment, you will write a program that encrypts and decrypts text files by simulating a two-rotor Enigma machine, as used by German forces in WWII.
The figure to the right shows a two-rotor Enigma machine with a reduced alphabet.
Rotors 1 (the inner wheel) and 2 (the middle wheel) can rotate clockwise,
while the backplate (the outer wheel) is stationary. The
numbers around the backplate indicate positions.
To encrypt a character, call it the input character, using this machine, locate the input character on rotor 1. Next, identify the character on the backplate at the same position. Let's call this the backplate character. Now locate the backplate character on rotor 2. The encryption of the input character is the character on the backplate at the same position as the backplate character's position on rotor 2. For example, if the input character is 'A' and since the position of 'A' on rotor 1 is 10, the backplate character will be 'C'. Since 'C' is located at position 12 on rotor 2, 'A' is encrypted by character 'B', the character on the backplate at position 12. After the encryption character has been determined, rotor 1 is advanced one position in the clockwise direction. When rotor 1 completes a full revolution by returning to its original positioning, rotor 2 advances one position in the clockwise direction. This is similar to how the minutes and hours advance on a clock.
The decryption process starts
with an encrypted character and determines the corresponding input character. This
is done by simply reversing the steps followed to determine the encryption character
during the encryption process. As long as the decryption process starts out with the
two rotors and the backplate positioned exactly as they were when the encryption process
started out, decrypting an encrypted version of a file should result in exactly
the original file.
To simulate an Enigma machine, you will use three id-name tables, one table for each of the two rotors and one for the backplate. The alphabet used will be the entire ASCII character set, including non-printing control characters. As there are 128 different ASCII characters, rotors and backplates will have 128 positions each, and the id's in the corresponding id-name tables will be 0 through 127, inclusive. Each name in the tables will be a Text string of length 1, containg exactly one ASCII character. Since all names in an id-name table must be unique, it follows that names in each table contain exactly the ASCII character set.
The process for encrypting a file will be given an input stream open to a
text file. As each character is read from the input stream, an encryption character
is determined, as described above, and output to an output stream. The process for
decrypting a file will be given an input stream open to an encrypted
text file. As each character is read from the input stream, a decryption character
is determined, as described above, and output to an output stream.
mkdir lab05
cd lab05
cp -R /class/sce/now/221/labs/catalogs/lab05/* .NOTE: The period . is part of the command. It denotes the current directory (folder).
This "copy command" will copy recursively (because of the "-R") all the files and directories from the shared class directory into your directory, effectively duplicating the entire substructure from the class directory into your directory.
lsYou should see the following files:
Enigma_Demo is an executable version of the solution for this assignment. Users of Enigma_Demo have the option of encrytping a file, decrypting a file, or quitting. You can run Enigma_Demo by typing the command Enigma_Demo in an xterm window. The section below, titled Using Enigma_Demo, shows an example of how to use Enigma_Demo.
sandburg.txt, shakespeare.txt, homer.txt, and homer_bk_1.txt are text files that you can use for test cases. (WARNING: homer_bk_1.txt takes a long time to encrypt/decrypt. You might not want to use it for testing until the last step of this assignment where you will improve the efficiency of the encryption/decryption processes.) sandburg.enc, shakespeare.enc, homer.enc, and homer_bk_1.enc are encrypted versions of sandburg.txt, shakespeare.txt, homer.txt, and homer_bk_1.txt, respectively. These encrypted files are provided to help you with testing, as described below.
Enigma.cpp is a skeleton for the solution to this assignment. You need to provide operation bodies for the following operations:
diff correct_small.enc my_small.encIF the the two files are identical, character-for-character, the "difference" command will produce NO output. IF the the two files are not identical, character-for-character, the "difference" command will produce output that, for now, is unintelligable. This unintelligable output indicates that there is a bug in your implementation of Enigma.cpp.
Also, do not forget that it is easy to look at the contents of a file using the Linux less command:
less my_small.enc
To remove calls to Advance_Rotor in Encrypt_File, use two local
Integer objects in the body of Encrypt_File, let's call them
adv_cnt_1 and adv_cnt_2,
that keep track of the number of times that Advance_Rotor would have been called
for rotors 1 and 2, respectively. Further,
suppose that the value of adv_cnt_1 is 3, for example, and suppose
that a "look-up"
operation for rotor 1 locates "A" at position 21 on rotor 1. Then, we should
think of "A" as being located at position 24 on rotor 1, instead of at position 21,
since rotor 1 should have been advanced 3 times by calls to Advance_Rotor.
Compile and test your new implementation of Encrypt_File.
object Character_IStream input_file; object Character chTo read a single character from input_file, use the operation
input_file.Read (ch);To test whether there are any more characters in input_file, use the Boolean-valued expression input_file.At_EOS () in a statement like
while (not input_file.At_EOS ())
input_ch_as_text.Add (0, input_ch).
Here is an example of how to use Enigma_Demo, and of how your solution for this assignment should function. User responses appear in bold face. The "progress" messages, such as
Enigma.cpp (190): Encrypt_File
100 characters have been encrypted
that you see below were generated by using a debug statement in the
body of the global operation Encrypt_File. You may want to do
something similar during testing/debugging to see if Encrypt_File
is making progress.
-------------------------------------------------
Command: e [Encrypt a file]
d [Decrypt a file]
q [Quit]: e
Enter the name of a file to be encrypted: homer.txt
Enter a name for the encrypted file: homer.enc
Encrypting file ...
Enigma.cpp (190): Encrypt_File
50 characters have been encrypted
Enigma.cpp (190): Encrypt_File
100 characters have been encrypted
Enigma.cpp (190): Encrypt_File
150 characters have been encrypted
Enigma.cpp (190): Encrypt_File
200 characters have been encrypted
Enigma.cpp (190): Encrypt_File
250 characters have been encrypted
Enigma.cpp (190): Encrypt_File
300 characters have been encrypted
Enigma.cpp (190): Encrypt_File
350 characters have been encrypted
Enigma.cpp (190): Encrypt_File
400 characters have been encrypted
Enigma.cpp (190): Encrypt_File
450 characters have been encrypted
Enigma.cpp (190): Encrypt_File
500 characters have been encrypted
Enigma.cpp (190): Encrypt_File
550 characters have been encrypted
Enigma.cpp (190): Encrypt_File
600 characters have been encrypted
Enigma.cpp (190): Encrypt_File
650 characters have been encrypted
Enigma.cpp (190): Encrypt_File
700 characters have been encrypted
Enigma.cpp (190): Encrypt_File
750 characters have been encrypted
Enigma.cpp (190): Encrypt_File
800 characters have been encrypted
Enigma.cpp (190): Encrypt_File
850 characters have been encrypted
Enigma.cpp (190): Encrypt_File
900 characters have been encrypted
Enigma.cpp (190): Encrypt_File
950 characters have been encrypted
... encryption completed.
-------------------------------------------------
Command: e [Encrypt a file]
d [Decrypt a file]
q [Quit]: d
Enter the name of a file to be decrypted: homer.enc
Enter a name for the decrypted file: homer.dec
Decrypting file ...
Enigma.cpp (257): Decrypt_File
50 characters have been decrypted
Enigma.cpp (257): Decrypt_File
100 characters have been decrypted
Enigma.cpp (257): Decrypt_File
150 characters have been decrypted
Enigma.cpp (257): Decrypt_File
200 characters have been decrypted
Enigma.cpp (257): Decrypt_File
250 characters have been decrypted
Enigma.cpp (257): Decrypt_File
300 characters have been decrypted
Enigma.cpp (257): Decrypt_File
350 characters have been decrypted
Enigma.cpp (257): Decrypt_File
400 characters have been decrypted
Enigma.cpp (257): Decrypt_File
450 characters have been decrypted
Enigma.cpp (257): Decrypt_File
500 characters have been decrypted
Enigma.cpp (257): Decrypt_File
550 characters have been decrypted
Enigma.cpp (257): Decrypt_File
600 characters have been decrypted
Enigma.cpp (257): Decrypt_File
650 characters have been decrypted
Enigma.cpp (257): Decrypt_File
700 characters have been decrypted
Enigma.cpp (257): Decrypt_File
750 characters have been decrypted
Enigma.cpp (257): Decrypt_File
800 characters have been decrypted
Enigma.cpp (257): Decrypt_File
850 characters have been decrypted
Enigma.cpp (257): Decrypt_File
900 characters have been decrypted
Enigma.cpp (257): Decrypt_File
950 characters have been decrypted
... decryption completed.
-------------------------------------------------
Command: e [Encrypt a file]
d [Decrypt a file]
q [Quit]: q
*** Quitting the Enigma program
The rcpp-submit command for this lab assignment is:
rcpp-submit c221xx lab05
where "xx" is to be replaced by lower case letters designating your section (see the course home page for a list).