The Caesar cipher has exactly 26 possible shifts (modulo the 26 letters of the alphabet). A Python script that tests all 26 shifts and looks for picoCTF in the result finds the right one in a fraction of a second.
| Platform | picoGym |
| Category | Cryptography |
| Points | 100 pts |
| Difficulty | Beginner |
| Technique | Caesar cipher, brute force |
The challenge provides a ciphertext and a hint that clearly points the way:
"I made my really long password more secure by adding 26 to each letter... modulo the number of letters."
tmgsgxj{________________________}
The word "modulo" combined with text that looks like letters shuffled in a regular pattern is a strong hint toward a Caesar cipher.
The Caesar cipher is one of the oldest known ciphers: each letter of the plaintext is replaced by the letter located n positions further in the alphabet, where n is the shift (the key). For example, with a shift of 3: A→D, B→E, C→F, etc. Once we reach Z, we wrap back around to A — hence the "modulo 26" in the hint, since the Latin alphabet has 26 letters.
Mathematically, for a letter at position p in the alphabet (A=0, B=1, ..., Z=25) and a shift k:
encryption: c = (p + k) mod 26
decryption: p = (c - k) mod 26
Caesar's fundamental weakness is that the key space is ridiculously small: there are only 26 possible shifts (0 to 25), one of which does nothing (shift 0) and one of which is the famous ROT13 (shift 13). No need to guess anything: we test all 26 in a loop and see which one produces readable text.
def caesar_decrypt(text, shift):
result = []
for ch in text:
if ch.isalpha():
base = ord('A') if ch.isupper() else ord('a')
decoded = chr((ord(ch) - base - shift) % 26 + base)
result.append(decoded)
else:
result.append(ch) # leave digits, punctuation, spaces untouched
return ''.join(result)
ciphertext = "tmgsgxj{________________________}"
for shift in range(26):
print(f"shift {shift:2d} : {caesar_decrypt(ciphertext, shift)}")
Running the script gives us 26 lines of output. Most are gibberish, but one jumps right out — the one starting with picoCTF{:
shift 0 : tmgsgxj{________________________}
shift 1 : slfrfwi{...}
...
shift 3 : qjdpduf{...}
shift 4 : picoctf{________________________}
shift 5 : ohbnbse{...}
...
shift 13 : ghtdtjy{...}
...
Shift 4 gives perfectly readable text, with the expected prefix picoctf{ — that's our shift. In practice, you just scan the 26 lines by eye, or script the detection by automatically searching for the substring picoctf{ in each output.
The flag is deliberately hidden — follow the method, you've earned it. 💪
Caesar is the textbook example of a cipher "broken by design": its security relies entirely on the secrecy of the method, not on mathematical robustness. As soon as you know it's Caesar, the key is found instantly.
picoCTF{) across the 26 outputs lets you fully automate detecting the right shift, with no manual readingSolving a monoalphabetic substitution cipher with frequency analysis.
Discuss this writeup with the community on the CTFdojo Discord.
Join the Discord →