Students break Caesar ciphers by trying every key, learn that the number of possible keys decides strength, and capture their first flag.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict and Run 8 min · Investigate 10 min · Modify 6 min · Flag 10 min (typical)
The idea: a cipher's strength comes from how many keys there are to try and how little the cipher text gives away. The Caesar cipher has 25. A computer tries them all in a blink; a person with the program tries them in a minute.
Framing for students: this is how codes are tested. Everyone here is breaking messages given to them, as a code designer does before trusting a code. We are not breaking anyone's private messages.
Letter counts: in English E is the most common letter, then T, A, O. In a long Caesar cipher text the most common letter is probably E shifted by the key. Do the Investigate task on the board together.
Flags: a flag is the answer to a puzzle in a fixed form, WP{...}. The page stores only a scrambled fingerprint (a hash) of the right answer, so view source does not give it away. The answer is below in the notes: WP{keys matter}.
Trying every key systematically and spotting readable text. Ask how many keys there are and how they'll know which one is right.
| What you will see | A question to ask | The fix |
|---|---|---|
| The flag is not accepted. | Did you type WP{ then the message in lower case, then }? Is the space in the right place? | The message has a space in the middle: WP{keys matter}. |
| Nothing readable appears for any key. | Did you change the cipher text in the program? | Start again from the step's starter. |
One possible solution for each task. Other correct programs are fine.

let ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let guess = 0
let secret = "KHOOR"
let tries = 0
function shift(letter: string, key: number): string {
let place = ALPHABET.indexOf(letter)
if (place < 0) {
return letter
}
return ALPHABET.charAt((place + key) % 26)
}
function encrypt(message: string, key: number): string {
let result = ""
for (let i = 0; i < message.length; i++) {
result = result + shift(message.charAt(i), key)
}
return result
}
function decrypt(message: string, key: number): string {
return encrypt(message, 26 - key)
}
input.onButtonPressed(Button.A, function () {
guess += 1
tries += 1
if (guess > 25) {
guess = 1
}
basic.showNumber(guess)
basic.showString(decrypt(secret, guess))
})
input.onButtonPressed(Button.B, function () {
basic.showNumber(tries)
})
Open task: any program that does what the step asks.
Stretch: Add a third button that tries the next key by itself every second and stops when you press it.
Support: Tell students to read each attempt aloud and say 'sense or nonsense'.
Why can a Caesar cipher be broken so quickly?
There are only 25 keys, so trying them all is quick; letter counts shorten it further.
Next: a cipher with a much bigger key.