Project 22: Caesar Cipher Club 🔐¶

Difficulty: 🟢 Beginner

Run cells top to bottom. Each step builds on the previous one and saves real files under outputs/caesar_cipher_club/.

← Back to index

Description¶

Encrypt secret notes with the classic Caesar cipher, then crack them by brute force.

Libraries & Modules¶

  • Built-in: string

Python Concepts You'll Practice¶

String transforms, modular arithmetic, functions

🎛️ Parameter Variations¶

  • SHIFT — encryption key (1–25)
  • MESSAGE — your secret text
  • ALPHABET — letters to shift
In [1]:
# Install dependencies for this project (safe to re-run)
import sys
!{sys.executable} -m pip install pillow numpy matplotlib wordcloud qrcode[pil] python-barcode fpdf2 jinja2 folium plotly pandas scipy ipywidgets -q
Skipping pip install (already installed)
In [2]:
# Interactive Jupyter setup — run this cell first
%matplotlib inline

from pathlib import Path
from IPython.display import display, Image as IPImage, HTML, Markdown, Audio, IFrame

OUTPUT_DIR = Path("outputs") / "caesar_cipher_club"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
print(f"✅ Outputs folder: {OUTPUT_DIR.resolve()}")
✅ Outputs folder: C:\Users\Hansel Yan\Projects\CodeItAll\outputs\caesar_cipher_club

Step 1 — Encode a secret message¶

In [3]:
# 🎛️ TWEAK THESE
MESSAGE = "Meet me at the CodeItAll cafe at noon!"
SHIFT = 7

def caesar(text, shift):
    out = []
    for ch in text:
        if "a" <= ch <= "z":
            out.append(chr((ord(ch) - 97 + shift) % 26 + 97))
        elif "A" <= ch <= "Z":
            out.append(chr((ord(ch) - 65 + shift) % 26 + 65))
        else:
            out.append(ch)
    return "".join(out)

secret = caesar(MESSAGE, SHIFT)
print("Plain :", MESSAGE)
print("Secret:", secret)
(OUTPUT_DIR / "cipher_secret.txt").write_text(secret, encoding="utf-8")
Plain : Meet me at the CodeItAll cafe at noon!
Secret: Tlla tl ha aol JvklPaHss jhml ha uvvu!
Out[3]:
38

Step 2 — Brute-force every shift¶

In [4]:
candidates = []
for s in range(26):
    unlocked = caesar(secret, -s)
    candidates.append(f"shift {s:2d}: {unlocked}")
report = "\n".join(candidates)
print(report)
(OUTPUT_DIR / "cipher_bruteforce.txt").write_text(report, encoding="utf-8")
print("Best guess (original shift):", caesar(secret, -SHIFT))
shift  0: Tlla tl ha aol JvklPaHss jhml ha uvvu!
shift  1: Skkz sk gz znk IujkOzGrr iglk gz tuut!
shift  2: Rjjy rj fy ymj HtijNyFqq hfkj fy stts!
shift  3: Qiix qi ex xli GshiMxEpp geji ex rssr!
shift  4: Phhw ph dw wkh FrghLwDoo fdih dw qrrq!
shift  5: Oggv og cv vjg EqfgKvCnn echg cv pqqp!
shift  6: Nffu nf bu uif DpefJuBmm dbgf bu oppo!
shift  7: Meet me at the CodeItAll cafe at noon!
shift  8: Ldds ld zs sgd BncdHsZkk bzed zs mnnm!
shift  9: Kccr kc yr rfc AmbcGrYjj aydc yr lmml!
shift 10: Jbbq jb xq qeb ZlabFqXii zxcb xq kllk!
shift 11: Iaap ia wp pda YkzaEpWhh ywba wp jkkj!
shift 12: Hzzo hz vo ocz XjyzDoVgg xvaz vo ijji!
shift 13: Gyyn gy un nby WixyCnUff wuzy un hiih!
shift 14: Fxxm fx tm max VhwxBmTee vtyx tm ghhg!
shift 15: Ewwl ew sl lzw UgvwAlSdd usxw sl fggf!
shift 16: Dvvk dv rk kyv TfuvZkRcc trwv rk effe!
shift 17: Cuuj cu qj jxu SetuYjQbb sqvu qj deed!
shift 18: Btti bt pi iwt RdstXiPaa rput pi cddc!
shift 19: Assh as oh hvs QcrsWhOzz qots oh bccb!
shift 20: Zrrg zr ng gur PbqrVgNyy pnsr ng abba!
shift 21: Yqqf yq mf ftq OapqUfMxx omrq mf zaaz!
shift 22: Xppe xp le esp NzopTeLww nlqp le yzzy!
shift 23: Wood wo kd dro MynoSdKvv mkpo kd xyyx!
shift 24: Vnnc vn jc cqn LxmnRcJuu ljon jc wxxw!
shift 25: Ummb um ib bpm KwlmQbItt kinm ib vwwv!
Best guess (original shift): Meet me at the CodeItAll cafe at noon!

✅ Project complete¶

Check your output folder: outputs/caesar_cipher_club/

Next: Project 23: Band Name Blender · Index