Fun With Python: Intro To Cryptography - Caesar and ROT13
Hey Everyone,
Sorry for not posting yesterday. I was planning to, but I got stuck down a deep rabbit hole last night. I wanted to start a new branch of the "Fun with Python" series that could also serve as an introduction to cryptography, which is what today's post is all about.
Intro to Cryptography: The Caesar Cipher
Probably one of the most well-known and simplest cryptography algorithms is the Caesar cipher. It's a type of substitution cipher where each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a shift of 3, 'A' would become 'D', 'B' would become 'E', and so on.
Its more modern and well-known relative is ROT13, which is just a Caesar cipher with a fixed shift of 13. The fun thing about ROT13 is that it's reciprocal; applying the same operation twice gets you back to your original text.
Here are a couple of simple Python scripts to demonstrate.
caesar.py
This script can handle any shift value, for both encrypting and decrypting.
#!/usr/bin/env python3
import argparse
def caesar_cipher(text, shift, decrypt=False):
"""
Applies the Caesar cipher to a given text with a given shift.
Handles both uppercase and lowercase letters, preserving case.
Non-letter characters are left unchanged.
:param text: The text to be processed.
:param shift: The shift amount (integer).
:param decrypt: If True, shifts backward for decryption.
:return: The processed text.
"""
if not text:
raise ValueError("Text cannot be empty.")
result = []
effective_shift = shift if not decrypt else -shift
for char in text:
if char.isupper():
base = ord("A")
new_char = chr((ord(char) - base + effective_shift) % 26 + base)
result.append(new_char)
elif char.islower():
base = ord("a")
new_char = chr((ord(char) - base + effective_shift) % 26 + base)
result.append(new_char)
else:
result.append(char)
return "".join(result)
def main():
parser = argparse.ArgumentParser(description="Caesar Cipher")
parser.add_argument("text", help="Text to encrypt/decrypt")
parser.add_argument("shift", type=int, help="Shift amount")
parser.add_argument(
"--decrypt", action="store_true", help="Decrypt instead of encrypt"
)
args = parser.parse_args()
try:
result = caesar_cipher(args.text, args.shift, args.decrypt)
print(f"Result: {result}")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
rot13.py
And here is a dedicated script just for ROT13.
#!/usr/bin/env python3
import argparse
def rot13_cipher(text):
"""
Applies the ROT13 cipher to a given text.
ROT13 is a Caesar cipher with a fixed shift of 13.
It is reciprocal: applying it again decrypts the text.
Handles both uppercase and lowercase letters, preserving case.
Non-letter characters are left unchanged.
:param text: The text to be processed.
:return: The processed text.
"""
if not text:
raise ValueError("Text cannot be empty.")
result = []
shift = 13
for char in text:
if char.isupper():
base = ord("A")
new_char = chr((ord(char) - base + shift) % 26 + base)
result.append(new_char)
elif char.islower():
base = ord("a")
new_char = chr((ord(char) - base + shift) % 26 + base)
result.append(new_char)
else:
result.append(char)
return "".join(result)
def main():
parser = argparse.ArgumentParser(description="ROT13 Cipher")
parser.add_argument("text", help="Text to process with ROT13")
args = parser.parse_args()
try:
result = rot13_cipher(args.text)
print(f"Result: {result}")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
As you can see, running ROT13 is the same as running the Caesar cipher with a shift of 13.
About That Rabbit Hole...
So, what sent me down this rabbit hole? While researching different ciphers we could play with, I got curious: "I've always wondered how the Enigma Machine works. How hard could it be? It was made in the 1930s, right?"
Oof. Boy, do I have some serious respect for the people who created that thing, and for the codebreakers who broke it during WWII. It was a bit of a journey, but the end result was worth it.
Let's just say I have a fully historically accurate recreation of the Enigma I machine... but that's going to have to be a post for another day.
As always,
Michael Garcia a.k.a. TheCrazyGM
Leave Fun With Python: Intro To Cryptography - Caesar and ROT13 to:
Read more #dev posts
Best Posts From Michael Garcia
We have not curated any of thecrazygm's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From Michael Garcia
- An Accidental Stress Test for Hive-Engine Data Integrity
- Fixing Data Integrity Issues in Hive-Engine Nodes
- The Final Chapter: dCity's 70,000 HIVE Claimdrop Has Been Distributed!
- Anther v0.1.0: A Modern Go SDK for Building on Hive
- Redesigning the Project Builder (GET FEATURED!)
- HiveTools Workbench: A Week of Polish, Pollen, and Splinterlands Wallets
- Pollen: A Safer, Cleaner Path Forward for Hive JavaScript Developers
- NectarPay Is Live, and Solana USDC Payments Are Working
- NectarPay Needs One Brave Hive Account Tester
- Lightning Strikes Twice: Upbit Triggers a 45-Million Hive Mega-Pump
- A Massive Makeover for the Mithril Diesel Pool (And Other HiveTools Updates)
- Nectar and NectarEngine v1.0.0 are Live on srbde
- HiveTools Post Curation Tool Now Filters By Language
- Finally Fixing the Little Docs Glitches in Hive-Nectar and NectarEngine
- The OGL/ORC Puzzle: Why We're Using a 25-Year-Old License on Purpose
- Hardening the Gopher Hole: A Security Audit of Go4Hive
- The Kimchi Premium Returns: Analyzing the 50% Hive Spike
- Go4Hive: Bringing the Gopher Spirit back to the Blockchain
- Modernizing MagnetBank: From legacy bloat to a lean, Neon-Powered Monorepo
- The Hive-Engine Failover Fix Is in Main