The goal of this lab is to introduce you to basic concepts in the C++ program language. Concepts you will be familiar with after this lab include:
A skeleton version the program will appear in your
cs35/labs/02 directory when you run update35. The
program handin35 will only submit files in this directory.
In this and most future labs, you'll work with one partner (there is one group of three).
I am assigning partners for this lab; find your partner in this file.
Useful links:
In the extras directory of this lab, there are a couple of text
files, along with encryptions of each file using each encryption
scheme you'll have to implement for this lab. Use these to compare
against your encrypt implementations, and compare your decrypted files
with the original text file to make sure you're encrypting and
decrypting correctly.
Encryption is the process of encoding messages in such a way that only authorized parties can read the message. The idea of encrypting messages is thousands of years old and has been particularly useful in the military, where it is important to exchange messages (e.g. "Attack at dawn!" vs "Hold your ground") without enemies being able to understand them in the event a message is intercepted. A cipher is a kind of encryption scheme where each letter is replaced by another. Ciphers have been used since at least Roman times. Julius Caesar used an cipher where each letter of the message was replaced with one three positions earlier in the alphabet. So, for instance, 'A' is encrypted as 'X', 'B' becomes 'Y', 'C' is encrypted as 'Z', 'D' is encrypted as 'A', and so on. An encrypted message is called the ciphertext, and if an enemy intercepted a message, it would just look like a jumble of letters. On the other hand, Caesar's subordinates, knowing the encryption scheme, could decrypt the message by employing doing the opposite of the encryption scheme: 'A' is decrypted as 'D', 'B' is decrypted as 'E', etc. This cipher was used so effectively that it became known as the Caesar cipher. In this lab, you will implement the following ciphers:
The essential flow of your program will be as follows: The user
specifies whether they want to encrypt or decrypt. Then they must
specifiy input and output files and the cipher they wish to use.
Finally, your program must use the requested cipher to encrypt or
decrypt the input file, writing it to the output file.
I recommend implementing your lab assignment in 4 phases:
You should complete the following items:
Your program will need to handle opening, reading, closing, and writing to file.
string inputFileName = "message.txt"; // get this filename from user ifstream inputFile(inputFileName.c_str());
The 356 blueYou can use the code:
string word, color; int number; input >> word; //"The" input >> number; //356 input >> color; //"blue"Notice that the strings do not contain whitespace, and that it automatically skipped the whitespace between 356 and blue.
char c; input >> c; // 'T' input >> c; // 'h' input >> c; // 'e' input >> c; // '3' input >> c; // '5' ...Notice that whitespace is still skipped even though characters are being read one at a time.
string outName = "output.txt"; ofstream outputFile(outName.c_str()); output << word << endl; output << number << " " << color << endl;
Example text files are available in the input folder in your labs directory for this week.
Review of requirements before moving forward:Once you are able to replicate a text file, you can begin writing your encryption and decryption functions. At this stage, you should implement encryption and decryption functions for the Caesar, ROT13, and substitution ciphers. Hold off on implementing the Enigma cipher until the last stage. Let's begin with the encryption function for the Caesar cipher.
void caesar_encrypt(ifstream& inFile, ofstream& outFile); void caesar_decrypt(ifstream& inFile, ofstream& outFile);The caesar_encrypt function takes references to already opened input and output file streams. It then reads in one character at a time, encrypts according to the Caesar cipher, and writes the corresponding character out to the output stream. The caesar_decrypt does something similar, decrypting characters instead of encrypting them.
Managing the encryption and decryption. So you read in a letter 'K' and are encrypting using the Caesar cipher. How does your lab figure out that 'H' is the encrypted character? More generally, with an arbitrary cipher, how should the data be structured to manage the encryption? There are several different possibilities, but the most straightforward is to use arrays. In the case of the Caesar cipher, the most straightforward solution is to use a character array:
char alphabet[] = {'A','B','C','D','E','F','G', 'H','I', 'J', 'K','L','M','N','O','P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};When encrypting a character, search through this array (using a for loop) until you find the index of the character to encrypt. Then subtract 3 from the index and output that character. Warning: you will need to handle the case where the cipher "wraps around" e.g. when you want to encrypt 'B' as 'Y'.
Managing arbitrary substitutions in the substitution cipher. The Substitution cipher allows arbitrary substitutions. You should enable the user to pick any permutations she likes. To enable arbitrary permutations here, load a substitution alphabet from a file and store it in a second character array. The format of your file should be just a permutation of characters, such as the example in input/subalpha:
KJRTPEQFBHYLZDOCMASWUVNXIGYour substitution cipher should take this setting and use it to encrypt 'A' as 'K', 'B' as 'J', 'C' as 'R', and so on.
Handling nonalphabetic characters. In this lab you can assume that the text consists of all capital letters, along with possibly some whitespace, which you can ignore. What happens if the text contains characters which are not capital letters, such as lower case letters, numbers, or punctuation? For this lab, feel free to ignore these characters -- if one appears, just leave it out of the encryption and read in the next character. In the real world, these characters might be (i) ignored, (ii) written to the output file without encrypting them, or (iii) encrypting them using some other means. Again, for this lab, you should ignore these characters.
Greet user. Ask user if they want to encrypt, decrypt, or exit. Repeat the following until the user chooses to exit. Ask user for input file (check if valid) Ask user for output file Ask user which encryption/decryption scheme he/she wants to use. If necessary, load settings for the chosen encrypyion/decryption scheme. For each character in the text: read in the character encrypt or decrypt the character using the cipher chosen by the user write character to output file. Close input and output files.There are multiple ways to implement this user interface. One possible solution is to implement three menus:
Your program should either encrypt or decrypt the chosen input file as demanded by the user. At all times, you should practice defensive programming.
Initial Enigma Settings. Like the substitution cipher, you should read in from a file both (i) the initial offset for the inner and middle rotors and (ii) the fixed permutation for each rotor. The format for this file should be as follows. The first line contains integers denoting the inner rotor offset and middle rotor offset respectively. The second, third, and fourth lines contain the information for the inner, middle, and outer rotors respectively. There is an example enigma settings file in input/enigmasettings.
Hint: to implement the enigma cipher, I recommend using character arrays for each rotor. Use integer variables (say inner_offset and middle_offset) to maintain the offsets. In this way, the state of the inner rotor would be implemented with (i) an array of chars and (ii) an offset. If 'D' is the first element of the array and the offset=3, then this character would align with the fourth character in the outer array.
Hint 2: decrypting the enigma cipher can seem complicated, but you still want to do essentially the opposite of the encryption. Specifically, perform the following:
Once you are satisfied with your code, hand it in by typing handin35. This will copy the code from your cs35/labs/02 to my grading directory. You may run handin35 as many times as you like, and only the most recent submission will be recorded.
The Enigma Machine cipher part of the lab is based on David Reed's NIFTY 2009 submission entitled "Enigma Encryption".