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.")
|