This homework is designed to refresh your programming skills and review what you already know. Although the concepts in this program should be mostly review, some students in previous years have found the assignment a challenge. Therefore I recommend getting started sooner rather than later: we don't learn well in a rush. Since most students will have taken CSC 111 at Smith I will assume that your background is in Python, but it is acceptable to complete this assignment in a different language if that is more comfortable for you.
You may work on a partner for this assignment if you adhere to the guidelines.
Unbreakable Encryption
One very simple strategy for unbreakable encryption involves the use of a mechanism known as a one time pad. This is simply a string of random characters known only to the sender and the recipient. Each consecutive character from the pad is added to a corresponding character of the message, thus shifting it by a random amount. Since each character is shifted independently, the end result is indistinguishable from a stream of random characters. There is no way to decipher it again without knowledge of the secret pad.
To make sure that you understand how the one time pad works, you should read this handout and decode the secret message included in it.
For this assignment you will write programs to add and subtract pads and messages, thus allowing you to encipher and decipher messages. The pad will be stored in an external file, and the message will be a Python string.
Specification
Name your file cipher.py. Your program should support the following interaction, assuming that pad.txt is a file containing the pad. Make sure you use exactly the same call signatures (function names and argument lists) as shown.
>>> msg = "This is an amazing secret message!" >>> pad = readFromFile("pad.txt") >>> cmsg = encipher(msg,pad) >>> decipher(cmsg,pad) 'This is an amazing secret message!' >>> cmsg 'Crsa is rm ljnoend igesxf mysvqnz!' >>>
You should write the functions readFromFile, encipher, and decipher yourself according to the descriptions in this document.
Use your program to decipher this enciphered quotation using the corresponding pad file. Save the result in a file called deciphered.txt.
When you have finished the program, you should write a short self-reflection on the assignment. How much did you remember right away from your previous experience? How much came back after working with the program for a little while? Did you learn anything new that you hadn't known before? What was the most challenging part?
More Detail
The diagram below shows how the coded message is computed from the pad. Note that the shift can be computed from the pad by taking the ASCII value of the pad character and subtracting 65. The message character is then shifted by that amount. Note also that punctuation and other non-letter characters are not changed at all, and don't use up a pad character.
Here is a suggested sequence of steps to accomplish the goal:
- Read the pad from the file and store in a string (review text file access in Python if necessary)
- Call a function that will transform the message:
- Make a list from the message characters just as we did in the Caesar cipher.
- Set up a counter to keep track of how many pad characters have been used.
- Loop over the characters in the list. For each one, test whether it is an alphabetic character. If so, shift it by the amount represented by the current pad character and increment the pad counter. Otherwise, leave it unchanged.
- Join the list of output characters into a string and return it.
You may use code from the Caesar cipher example as a starting point for this homework, if you think it would be useful.
Going Further
The section above concludes the assignment. If you would like to extend your work on your own, a nice project is to make your program callable from the command line. You can read more about command line arguments at these tutorials: Real Python, Tutorials Point. The basic idea is to create two modules, encipher.py and decipher.py, that act as stand-alone programs to encode and decode messages. Here's how you would use them from the command line:
$ python encipher.py plain_message.txt pad.txt $ python decipher.py coded_message.txt pad.txt
There are other projects you could try that have a more cryptographic flavor. Suppose that you have a message and the pad used to encode it, but the pad is very large and only a portion of it has been used. The characers used for encoding will all be contiguous, but may not start at the beginning of the file. Write a new program, cipher2.py that will print out all possible decipherments of a message, by trying each possible starting character in the pad. (For example, if the pad is 120 characters long, and the message is 100 letters, there are 21 possible places to start the message without running out of pad.)
It would be even better if your program could print out the most likely decipherment possibilities. You could rank them according to the appearance of known dictionary words, or letter frequency statistics close to natural English. This is not an easy program to write, but might be fun if you are looking for a challenge.
To Submit on Moodle
- cipher.py
- deciphered.txt
- readme.txt containing your self-reflection on this assignment
- encipher.py and decipher.py (if attempting the command-line task)