In the hush of a Roman camp, a messenger waits — and the alphabet learns a secret little step. Follow Julius Caesar’s famous cipher from ancient battlefield whispers to a clean Python function that shifts letters, wraps around, and turns “Hello World!” into something only the right reader can understand.
📖
The candles were low in the Roman camp, and the night sounded like leather straps settling, armor being set down, and a thousand quiet thoughts trying to become tomorrow’s plan.
A messenger waited at the edge of the lamplight, holding a small tablet. Not every message was meant for every eye. Some orders needed to cross distance without being understood by the wrong hands.
And that’s where the Alphabet entered the story.
📖
The Alphabet, as it turns out, is easy to teach and hard to gossip with. You simply tell it to walk a certain number of steps.
Julius Caesar did exactly that. The reason we call it Caesar Cipher is not because he invented the idea of shifting letters, but because he’s the earliest famous person recorded using it to protect private and military communication.
A Roman historian, Suetonius, describes Caesar writing confidential notes by shifting the letters so “not a word could be made out,” and he even explains the rule: substitute D for A, and keep going from there.
📖
That “D for A” detail is the whole secret in one breath: it’s a shift of 3.
- A → D
- B → E
- C → F
…and when you reach the end, you wrap around to the start again.
Caesar reportedly used this to send battlefield instructions to his generals and private letters to trusted friends — messages that would be annoying to intercept and much harder to casually read.
📖
Back then, the cipher worked better than it sounds to modern ears for two very practical reasons: literacy was limited, and systematic codebreaking wasn’t yet a standard craft.
The big “aha” that breaks many simple ciphers — frequency analysis, where you look at which letters appear most often — shows up much later in the historical record, in the 9th century with Al-Kindi, who wrote an early known description of this kind of cryptanalysis.
And the Alphabet, being a creature of habit, kept the trick in the family.
Suetonius also tells us that Caesar’s successor Augustus used a similar shift, but gentler: a shift of 1 (B for A, C for B…). In some accounts, he didn’t “wrap around” at the end; instead of turning Z into A, he reportedly wrote “AA” for Z.
📖
Now — two thousand years later — the campfires are different. They glow from laptop screens. The messengers are function calls. And the Alphabet still walks, perfectly obedient, whenever we ask it to.
But instead of writing by hand and counting letters one by one, Caesar would slip off his crown, pull up his hacker hoodie, and fire up Python to encrypt his messages — like this:
Hello World!
📖
How would he do it? By writing simple Python functions that encrypt every message leaving and decrypt every message appearing on his screen.
def caesar_cipher(text, shift, encrypt=True):
if not isinstance(shift, int):
return 'Must be an integer.'
if shift < 1 or shift > 26:
return 'Must be between 1 and 26.'
if not encrypt:
shift = - shift
abc = 'abcdefghijklmnopqrstuvwxyz'
abc_shift = abc[shift:] + abc[:shift]
t = str.maketrans(abc + abc.upper(), abc_shift + abc_shift.upper())
return text.translate(t)
def encrypt(text, shift):
return caesar_cipher(text, shift)
def decrypt(text, shift):
return caesar_cipher(text, shift, encrypt=False)
print(encrypt('Hello World!', 3)) # Output: Khoor Zruog!
print(decrypt('Khoor Zruog!', 3)) # Output: Hello World!
This caesar_cipher() function is the commander of the whole operation. It takes a piece of text, a shift amount, and a little flag that says whether we’re encrypting (walking forward) or decrypting (walking back).
First, it checks the rules — because a cipher that accepts anything becomes a cipher that surprises you later:
-
shiftmust be an integer, because the Alphabet only moves in whole steps. -
shiftmust be between 1 and 26, because English has 26 letters and you want the key to be meaningful.
Then comes the cleanest trick in the whole spell:
if not encrypt:
shift = - shift
To decrypt, you don’t need a separate algorithm. You just reverse the direction of the walk. Same machinery, opposite steps.
📖
Next, your Alphabet is introduced:
abc = 'abcdefghijklmnopqrstuvwxyz'
And then you build a shifted version:
abc_shift = abc[shift:] + abc[:shift]
This is the “circle” part. If the shift pushes letters past Z, they wrap around to the beginning. With a shift of 3, the shifted alphabet becomes:
defghijklmnopqrstuvwxyzabc
Now you create a translation table that covers both lowercase and uppercase:
t = str.maketrans(abc + abc.upper(), abc_shift + abc_shift.upper())
So A doesn’t get left behind just because it’s wearing a capital letter.
📖
Finally, the letters take their walk through the message:
return text.translate(t)
That’s the moment the messenger returns, tablet in hand, with the same message — only dressed differently.
Your helper functions are the friendly guards at the tent flap:
-
encrypt(text, shift)callscaesar_cipher()with the default settings. -
decrypt(text, shift)callscaesar_cipher()but flipsencrypt=False, which flips the shift direction.
And your test prints show the Alphabet behaving exactly as promised:
-
encrypt('Hello World!', 3)becomes "Khoor Zruog!" -
decrypt('Khoor Zruog!', 3)becomes "Hello World!"
📖
Somewhere in the quiet, Caesar would probably approve of that: simple, repeatable, and easy to explain to someone who just needs to send the order and move on.
Resources
https://lexundria.com/suet_jul/56.6/
https://en.wikipedia.org/wiki/Caesar_cipher
Top comments (0)