Encrypting and decrypting with a one-time pad in Python

Tip: Choose Save as PDF in the print dialog to download. Use A4 paper size.

Encrypting and decrypting with a one-time pad in Python

Name:
Date:
Class:

Quick Questions

Shade in the A or B circle for each question.

1. Which expression encrypts letter number m using key number k in a one-time pad?
A (m + k) % 26
B (m * k) % 26
2. Which expression decrypts cipher number c using the same key number k?
A (c + k) % 26
B (c - k) % 26
3. What does zip(message, key) do in a one-time pad program?
A Pairs each message letter with the key letter in the same position
B Joins the message and key into one long string
4. Message letter 'Y' is number 24 and the key number is 5. What is the encrypted number?
A 3, because (24 + 5) % 26 = 3
B 29, because 24 + 5 = 29
5. Cipher number c is 2 and the key number k is 5. What does (c - k) % 26 give in Python?
A -3
B 23

Match the Pairs

Draw a line connecting each item on the left to its match on the right.

Left columnRight column
1(m + k) % 26 ADecrypts one letter: subtract the same key number from the cipher letter number, then wrap back into 0-25
2(c - k) % 26 Bp = (ord(ch) - 65 - k) % 26
3zip pairs each message letter with the key number in the same position so they can be shifted together CDecryption adds the key instead of subtracting it, so the shift goes the wrong way and the original message is not recovered
4To decrypt a one-time pad, subtract the same key value from each cipher letter number and wrap with MOD 26 DThe % 26 is missing, so the result can go past 25 and will not wrap back around to a letter from A to Z
5c = (m + k) EEncrypts one letter: add the key number to the message letter number, then wrap back into 0-25
6p = (c + k) % 26 Ffor ch, k in zip(message, key):

Definitions

(m + k) % 26

Fill in the Blanks

Complete each line of code by filling in the missing parts.

1.
for m, k in ___(message, key):
2.
for m, k in zip(message, key): c = (m _ k) % 26
3.
for m, k in zip(message, key): c = (m + k) % __
4.
for c, k in zip(cipher, key): p = (c _ k) % 26
5.
for m, k in zip(message, key): c = (m + k) _ 26 cipher.append(c)

Spot the Error

Shade in the letter of the line that contains an error.

Question 1
A def encrypt(msg, key):
B for m, k in zip(msg):
C c = (m + k) % 26
D print(c)
Question 2
A msg = [2, 14, 3, 4]
B key = [9, 5, 17, 1]
C for m, k in zip(msg, key):
D print((m + k) % 25)
Question 3
A def decrypt(cipher):
B out = []
C for c, k in zip(cipher, key):
D out.append((c - k) % 26)
E return out
Question 4
A cipher = [10, 13, 12, 24
B key = [3, 8, 1, 20]
C for c, k in zip(cipher, key):
D print((c - k) % 26)
Question 5
A cipher = [10, 13, 12, 24]
B key = [3, 8, 1, 20]
C for c, k in zip(cipher, key):
D p = (c + k) % 26
E print(p)

Answer Key

Encrypting and decrypting with a one-time pad in Python
Section A: Quick Questions
Q1
A — (m + k) % 26
Q2
B — (c - k) % 26
Q3
A — Pairs each message letter with the key letter in the same position
Q4
A — 3, because (24 + 5) % 26 = 3
Q5
B — 23
Section B: Match the Pairs
Q1
(m + k) % 26 → Encrypts one letter: add the key number to the message letter number, then wrap back into 0-25
Q2
(c - k) % 26 → Decrypts one letter: subtract the same key number from the cipher letter number, then wrap back into 0-25
Q3
zip pairs each message letter with the key number in the same position so they can be shifted together → for ch, k in zip(message, key):
Q4
To decrypt a one-time pad, subtract the same key value from each cipher letter number and wrap with MOD 26 → p = (ord(ch) - 65 - k) % 26
Q5
c = (m + k) → The % 26 is missing, so the result can go past 25 and will not wrap back around to a letter from A to Z
Q6
p = (c + k) % 26 → Decryption adds the key instead of subtracting it, so the shift goes the wrong way and the original message is not recovered
Section C: Definitions
Q1
(m + k) % 26 — One-time pad: shift each message letter number m by the matching key number k, wrapping with % 26. To decrypt, subtract the same key values: (c - k) % 26. zip pairs each letter with its key.
Section D: Fill in the Blanks
Q1
for m, k in zip(message, key):
Q2
for m, k in zip(message, key): c = (m + k) % 26
Q3
for m, k in zip(message, key): c = (m + k) % 26
Q4
for c, k in zip(cipher, key): p = (c - k) % 26
Q5
for m, k in zip(message, key): c = (m + k) % 26 cipher.append(c)
Section E: Spot the Error
Q1
B — zip needs both lists to pair each message number m with its key number k. zip(msg) gives single items that cannot be unpacked into m, k. It should be zip(msg, key).
Q2
D — The alphabet has 26 letters, so the wrap-around must use % 26. Using % 25 gives the wrong cipher numbers. It should be (m + k) % 26.
Q3
A — The function loops over key with zip, so key must be a parameter. Without it the function raises a NameError. It should be def decrypt(cipher, key):
Q4
A — The list is missing its closing square bracket, which is a syntax error. It should be cipher = [10, 13, 12, 24].
Q5
D — Decryption must undo the encryption by subtracting the same key value. Adding the key shifts the letter further instead of back. It should be (c - k) % 26.