COS 100: Introduction to Programming
Interim 2022
HW Project 08: Decryption
Due: 01/24 Mon 10pm
Ktw ymjwj nx stymnsl htajwji ymfy bnqq sty gj wjajfqji, stw mniijs ymfy bnqq sty gj pstbs.
Qzpj 12:2
If you are pair programming, do NOT start coding without your partner.
You should read the assignment first, feel free to think about it, but do not actually start coding.
Project goal
Decrypt a message by using frequency analysis.Prerequisites
- Finish lab08 and lab09 first: they are designed to prepare you for this project.
- Finish hw07 first: you will need to use
caesar_cipher
.
Background information
- In the previous homework project, you wrote a program to encrypt a message by using the Caesar cipher.
- If a message has been encrypted/shifted with a key of 3, decrypting such a message is easy: just shift with a key of -3 and the original message pops right back out.
- However, what if you don't know the key?
- There is a major flaw of the Caesar cipher (and in fact, many substitution ciphers). Not all letters in the English language are used with the same frequency.
- If we assume that the letter 'e' occurs most frequently, then we can count the frequencies of all the letters in an encrypted message, and guess that such a letter is supposed to be decrypted as 'e'.
- This attack is known as frequency analysis.
Project specification
Write a program that- Prompts the user for an encrypted message.
- Counts how many times each letter of the alphabet occurs in that message.
- Prints out the letter counts for the whole alphabet.
- Tells the user what the most commonly occurring letter was. (In the event of a tie, go with the letter that appears earliest in the alphabet.)
- Decrypts the message by shifting the most frequent letter to the letter 'e'.
- Prints out the decrypted message.
Notes and hints
-
Name your project source code
decrypt.py
. - Break your code up into various small functions that each does one task. If your functions get too long (or you do everything inside the main function), you will lose points. For reference, my solution has 7 functions, each fewer than 10 lines.
-
You should reuse your
caesar_cipher
code fromencrypt.py
by copying it over. (In a future class, you will learn how to reuse code from other files without copying.) -
If your
caesar_cipher
function does not work, you ARE allowed to borrow code from a fellow student, PROVIDED you give credit where credit is due: write a comment to cite the source. -
If you want to ignore capitalization, you can convert a string to a lower case version of that string using
my_string = my_string.lower()
to only get lowercase letters (plus any punctuation marks). - You are forbidden from having 26 variables keeping track of each letter individually. This is where loops and lists will come in really handy.
- Watch out for characters that aren't letters. You only care about the characters 'a' through 'z' in this project.
-
You had labs where you wrote your own versions of counting letters and finding the largest number.
Use your own code.
Do not use the built-in
str.count()
ormax()
for this project. - For a small amount of extra credit, get your output format to be exactly the same as in the sample runs, down to the minute details of spacing, newlines, and punctuations.
Suggested order of development
This project is substantially more involved than previous projects. Plan before you code!-
Break this program down into the various tasks, and think hard about how you want to organize your program before you start to code it up. There are lots of little tasks that need to be accomplished, so don't just try to slam the whole thing together in one go.
One way to do this is to write a draft main function with things commented out, and slowly fill in details, like so:
def main(): message = input(...) #counts = calculate_counts(message) #print(counts) # this works, but later on I need to make it print prettier #figure out the most used letter, should I use a function? probably? #do some other things here? #caesar_cipher(message, ???)
Notice that I have a mixture of actual function names and some notes to myself. It's just a draft, do whatever is best for you. -
Here's a nice time-saving trick.
Instead of asking the user for a message, just hard code a string for now:
message = "Just a temporary test message; I'll change this to get input from user later."
This makes your testing easier as you develop because you can just run the program with the same string every time instead of always pausing to type in a string in the Shell. Actually, you might want to use one of the test messages provided in the sample runs below, so you know the counts that should show up. - Try counting how many times the letter 'a' shows up. (Didn't we do this in a practice lab already? You can just copy your code over. If you got substantial help from the professor, TA, classmates, tutors, etc., mention that in a comment. This is good practice.)
-
Use a loop,
chr
, andord
to print out the letters 'a' through 'z'. Do not write 26 statements, or type out "abc...z" yourself. Use a loop. Really. - Modify that loop to count all the letters, printing out the counts, one per line. (Don't worry about making this pretty yet.)
- Figure out how to collect those counts in a list instead of printing them out.
- Then figure out which letter showed up the most. (Didn't we have a practice lab that essentially already solves this part?)
-
Then decrypt using
caesar_cipher
.
Sample runs
-
Please enter an encrypted message: The quick brown fox jumps over the lazy dog. Letter counts: a: 1, b: 1, c: 1, d: 1, e: 3, f: 1, g: 1, h: 2, i: 1, j: 1, k: 1, l: 1, m: 1, n: 1, o: 4, p: 1, q: 1, r: 2, s: 1, t: 2, u: 2, v: 1, w: 1, x: 1, y: 1, z: 1. The most common letter was 'o'. A key of 16 will shift 'o' to 'e' and give: Jxu gkysa rhemd ven zkcfi eluh jxu bqpo tew.
-
Please enter an encrypted message: Rz'mz xgjnz oj wzdib mzvyt ajm Xjhkpozm Nxdzixz 105! Letter counts: a: 1, b: 1, c: 0, d: 2, e: 0, f: 0, g: 1, h: 1, i: 2, j: 4, k: 1, l: 0, m: 4, n: 2, o: 2, p: 1, q: 0, r: 1, s: 0, t: 1, u: 0, v: 1, w: 1, x: 4, y: 1, z: 8. The most common letter was 'z'. A key of 5 will shift 'z' to 'e' and give: We're close to being ready for Computer Science 105!
Grading
- Total points: 24
- Correctness: 20
- Style: 4
Start early, have fun, and discuss questions on Moodle.