51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
#!/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.") |