nerdletter/cipher/encrypt.py

51 lines
1.7 KiB
Python
Raw Normal View History

2026-04-28 12:20:50 +00:00
#!/usr/bin/env python3
import sys
from pathlib import Path
def load_pad(filename="cipher/data/daybook_master_example.txt"):
"""Load the master pad file."""
pad_text = Path(filename).read_text()
# Extract only the 5-letter groups, ignore headers and spaces
groups = [g for g in pad_text.split() if len(g) == 5 and g.isalpha()]
return "".join(groups).upper()
def encrypt_message(plaintext: str, pad: str, start_pos: int):
"""Encrypt using the pad starting at a given position."""
# Clean plaintext: uppercase letters only, remove everything else
pt = "".join(c for c in plaintext.upper() if c.isalpha())
if not pt:
return "ERROR: No letters in message"
ciphertext = []
for i, char in enumerate(pt):
if i + start_pos >= len(pad):
return "ERROR: Pad exhausted! Generate new master."
p = ord(pad[start_pos + i]) - 65
c = ord(char) - 65
d = (c + p) % 26
ciphertext.append(chr(d + 65))
# Format in 5-letter groups
ct_str = "".join(ciphertext)
return " ".join(ct_str[j:j + 5] for j in range(0, len(ct_str), 5))
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 encrypt.py 'Your secret message here' [start_page]")
print("Example: python3 encrypt.py 'Meeting at the retro show on Saturday' 7")
sys.exit(1)
message = sys.argv[1]
start_page = int(sys.argv[2]) if len(sys.argv) > 2 else 1
pad_str = load_pad()
# Each page = 50 letters (10 groups × 5)
start_pos = (start_page - 1) * 50
ct = encrypt_message(message, pad_str, start_pos)
print(f"\n=== NERDLETTER SECRET MESSAGE (Use Day Book PAGE {start_page:03d}) ===")
print(ct)
print("\nCopy the line above to the website.")