← QCE Digital Solutions Unit 4

Encrypting and decrypting with a one-time pad in Python

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.

Understanding Encrypting and decrypting with a one-time pad in Python in QCE Digital Solutions Unit 4

What it does: zip(message, key) gives one letter and one key value at a time, so each letter is shifted by its own matching key number. Subtracting k undoes the encryption shift. ord(ch) - 65 converts the letter to 0-25, and % 26 wraps the result back into the alphabet. Decryption reverses the shift, so you subtract the same key value and wrap with % 26. 29 is outside 0-25. The % 26 wraps it around to 3, which is the letter 'D'. Python's % always gives a result from 0 to 25 when the divisor is 26, so (2 - 5) % 26 is 23. This is why decryption still works for small cipher numbers.

Common mistakes: 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). 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.

Class: _____________________  ·  Name: _____________________  ·  Date: _________

Free printable worksheet with full answer key — or add this module to a class and your students practise it interactively.

This module's key terms are also in a printable crossword (Modules 334–401) and word search (Modules 127–401).

Take this worksheet further — free with Cloodit

Each concept is reinforced from every angle — learned, then applied, then tested.

Learning
Duo
Which expression encrypts letter number m using key number k in a one-time pad?
(m * k) % 26(m + k) % 26
Matches
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
Applying
Meanings
Term
(m + k) % 26
Meaning
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.
Practice
message = "HELLO"
Testing
Gaps
for m, k in (message, key):
Check Answer
Spots
1def encrypt(msg, key):
2 for m, k in zip(msg):

Cloodit turns curriculum-aligned coding content into journeys students work through one biome at a time.

The 'Gazelle' badge — Tuple Sprinter, one of Cloodit's 106 collectible badges
Students earn collectable badges

Over 100 of them, across seven natural biomes.

Study Buddy
Students build a real study resource

Turns their work into revision material ready for Flash Cards and Exam study.

Diamond Dash — one of Cloodit's live, competitive Sprint games
Students lock in with Sprints

Live, competitive practice for the start of the lesson or a teacher-led lesson finisher.

A Cloodit certificate of achievement, ready to personalise and print
Custom printable certificates

Honour your top performers, or encourage a student who's trying hard — ready to print in seconds.

Quick Questions

1. Which expression encrypts letter number m using key number k in a one-time pad?
A. (m + k) % 26 ✓
B. (m * k) % 26
A one-time pad shifts each letter number m forward by the matching key number k. The % 26 wraps the result back into the alphabet.
2. Which expression decrypts cipher number c using the same key number k?
A. (c + k) % 26
B. (c - k) % 26 ✓
Decryption reverses the shift, so you subtract the same key value and wrap with % 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
zip gives pairs like ('H', 'X'), so a loop can shift each letter by its own matching key value.
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
29 is outside 0-25. The % 26 wraps it around to 3, which is the letter 'D'.
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 ✓
Python's % always gives a result from 0 to 25 when the divisor is 26, so (2 - 5) % 26 is 23. This is why decryption still works for small cipher numbers.

Match the Pairs

(m + k) % 26 → Encrypts one letter: add the key number to the message letter number, then wrap back into 0-25
(c - k) % 26 → Decrypts one letter: subtract the same key number from the cipher letter number, then wrap back into 0-25
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):
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
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
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

Key Term

(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.

Fill in the Blanks

1. for m, k in zip(message, key):
Hint: Type the built-in function that pairs each message letter number with its matching key number.
2. for m, k in zip(message, key): c = (m + k) % 26
Hint: Type the arithmetic operator that shifts the message number forward by the key number when encrypting.
3. for m, k in zip(message, key): c = (m + k) % 26
Hint: Type the number of letters in the alphabet, used so the shifted value wraps around.
4. for c, k in zip(cipher, key): p = (c - k) % 26
Hint: Type the operator that undoes the encryption shift by using the same key value.
5. for m, k in zip(message, key): c = (m + k) % 26 cipher.append(c)
Hint: Type the modulo operator that wraps the shifted number back into the range 0 to 25.

Spot the Error

Question 1
A def encrypt(msg, key):
B for m, k in zip(msg):
C c = (m + k) % 26
D print(c)
Line 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).
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)
Line 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.
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
Line 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):
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)
Line A — The list is missing its closing square bracket, which is a syntax error. It should be cipher = [10, 13, 12, 24].
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)
Line 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.

Student with a class code? Join your class →