From bc49b72c9ecf8d37cc90cb088afb75c988fc0d1e Mon Sep 17 00:00:00 2001 From: Kenn Kitchen Date: Sun, 26 Oct 2025 13:34:05 -0400 Subject: [PATCH] Updated README and cleaned up the code some. Added type hints. --- README.md | 42 ++++++++++++++++++++++++++---------- main.py | 64 ++++++++++++++++++++----------------------------------- 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index e849f91..285d240 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,38 @@ # Enigma Machine -Recreates the functionality of the Enigma Machine from World War II. +Recreates the functionality of the Enigma Machine from World War II. Mainly just an exercise in Python. ## Usage -`uv run main.py [0-58] [0-58] [0-58] '[message]' 'e|d' [int]` +`uv run main.py "[message]" e|d [int]` + Where: -- 0-58 [integer] is the first seed value -- 0-58 [integer] is the second seed value -- 0-58 [integer] is the third seed value -- message is the message to be encrypted/decrypted -- e|d is the direction of the message (encrypt or decrypt) -- int is the number of iterations to be made (not yet implemented) +- __"[message]"__ is the message to be encrypted/decrypted. Should be in quotes. +- __e|d__ is the direction of the message (encrypt or decrypt). +- __int__ is the number of iterations to be made. -## Examples -`uv run main.py 32 15 1 'This is a test.' 'e' 3` +### Seed Values +When encrypting a message, a file will be written to the current directory. This file contains the seed values used to +generate the encryption/decryption keys. + +The seed values are integers between 0 and 58. In the file, each seed value is on a new line. + +The number of iterations should match the number of seed values used. + +### Examples +#### Encode +Encode the message "You are here." with three iterations. + +`uv run main.py "You are here." e 3` + +The command above will create a file called "seed_values.txt" with the generated seed values. + +#### Decode +Decode the message "NTb!QDbGDQDa" with three iterations. + +`uv run main.py '.NTb!QDbGDQDa' d 3` + +The command above expects a file called "seed_values.txt" with the seed values used to encode the message from the preceding example. + +## TODO +- [ ] Add a param to tell the `encode` function to use an existing seed file. -`uv run main.py 32 15 1 'Uijt!jt!b!uftu' 'd' 3` diff --git a/main.py b/main.py index e542233..3971ff3 100644 --- a/main.py +++ b/main.py @@ -2,48 +2,32 @@ import random import sys import time -alpha_base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,. !=" +# define the full range of characters used by this program +alpha_base: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,. !=" + +# MAIN def main(): ### Argument validation ### - if len(sys.argv) < 7: - print("Usage: uv run main.py [0-58] [0-58] [0-58] '[message]' 'e|d' [int]") + if len(sys.argv) < 4: + print("Usage: uv run main.py \"[message]\" e|d [int]") sys.exit(1) - base_max = len(alpha_base) + base_max: int = len(alpha_base) - if not is_number(sys.argv[1]) or not is_number(sys.argv[2]) or not is_number(sys.argv[3]): - print("Invalid seed value.") - sys.exit(1) - - if not is_number(sys.argv[6]): + if not is_number(sys.argv[3]): print("Invalid iterations value.") sys.exit(1) - if int(sys.argv[1]) == 0 or int(sys.argv[1]) > base_max: - seed1 = random.randint(1, base_max) - else: - seed1 = int(sys.argv[1]) - - if int(sys.argv[2]) == 0 or int(sys.argv[2]) > base_max: - seed2 = random.randint(1, base_max) - else: - seed2 = int(sys.argv[2]) - - if int(sys.argv[3]) == 0 or int(sys.argv[3]) > base_max: - seed3 = random.randint(1, base_max) - else: - seed3 = int(sys.argv[3]) - - if int(sys.argv[6]) < 0: + if int(sys.argv[3]) == 0: iterations = 3 else: - iterations = int(sys.argv[6]) + iterations = int(sys.argv[3]) ### Processing ### - seed_values = [] + seed_values: list[int] = [] - if sys.argv[5] == "e": + if sys.argv[2] == "e": with open("seeds.txt", "w") as f: for iteration in range(0, iterations): random.seed(time.time()) @@ -51,36 +35,34 @@ def main(): f.write(str(seed_values[iteration]) + "\n") f.close() - if sys.argv[5] == "d": + if sys.argv[2] == "d": with open("seeds.txt", "r") as f: for iteration in range(0, iterations): seed = f.readline() seed_values.append(int(seed)) f.close() - iteration_result = "" + iteration_result: str = "" - if sys.argv[5] == "e": + if sys.argv[2] == "e": print("Encoding!") for iteration in range(0, iterations): - iteration_result = encode(seed_values[iteration], sys.argv[4]) - # print("Seed:", iteration, "is", seed_values[iteration]) + iteration_result = encode(seed_values[iteration], sys.argv[1]) print("Result:", "\"" + iteration_result + "\"") - elif sys.argv[5] == "d": + elif sys.argv[2] == "d": print("Decoding!") for iteration in range(0, iterations): - iteration_result = decode(seed_values[iteration], sys.argv[4]) + iteration_result = decode(seed_values[iteration], sys.argv[1]) - # print("Seeds used:", seed1, seed2, seed3) print("Result:", "\"" + iteration_result + "\"") else: print("Invalid option!") sys.exit(1) -def encode(offset, message): - result_message = "" +def encode(offset: int, message: str) -> str: + result_message: str = "" for index_a in range(len(message)): for index_b in range(len(alpha_base)): @@ -94,8 +76,8 @@ def encode(offset, message): return result_message -def decode(offset, message): - result_message = "" +def decode(offset: int, message: str) -> str: + result_message: str = "" for index_a in range(len(message)): for index_b in range(len(alpha_base)): @@ -109,7 +91,7 @@ def decode(offset, message): return result_message -def is_number(i): +def is_number(i) -> bool: try: int(i) return True