From 1c906b0de9e5031b9e89bf57b0c3b718c33c4085 Mon Sep 17 00:00:00 2001 From: mdecker62 Date: Wed, 1 Apr 2026 10:02:49 -0400 Subject: [PATCH] checkpoint 1:Writing my own code for Checkpoint 1 was challenging at first, but it ended up helping me understand the problem much better. Instead of just thinking about how the Caesar cipher works, I had to actually apply the logic step-by-step in code. Using `Counter` to find the most common character and then calculating the shift made the idea of frequency analysis much clearer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At first, I struggled with errors and figuring out how everything connected, but once it worked, it made sense why the most common character could be used to guess the shift. Writing the code forced me to think about how characters are represented as numbers and how shifting works mathematically. Overall, coding the solution helped turn an abstract idea into something concrete, and it made me feel more confident solving similar problems in the future. checkpoint 2: To find the polyalphabetic secret word, I compared the given plaintext and ciphertext character by character. For each pair of characters, I calculated the shift by subtracting their ASCII values. This gave me a list of numbers representing how much each character was shifted. When I looked at the sequence of shifts, I noticed that the pattern repeated, which showed that the cipher was using a repeating key. From this repeating pattern, I was able to identify the secret word as “supersecret.” To decrypt the final message, I used the same key and applied it repeatedly across the ciphertext. For each character, I subtracted the corresponding key character’s value (looping through the key as needed). This reversed the encryption process and produced the original readable English message. This strategy worked because polyalphabetic ciphers rely on repeating shifts, so once the pattern is discovered, the entire message can be decrypted. --- answers.md | 13 +++++++------ caesar_cracker.py | 12 +++++------- caesar_cracker.py.save | 13 +++++++++++++ easybits.py | 21 +++++++++++++++++++++ 4 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 caesar_cracker.py.save create mode 100644 easybits.py diff --git a/answers.md b/answers.md index f125e69..165df03 100644 --- a/answers.md +++ b/answers.md @@ -3,23 +3,24 @@ ## Checkpoint 1 0. `secrets/secret0.txt` is encrypted using a Caesar Cipher. What is - its secret number? + its secret number? 78 1. `secrets/secret1.txt` is encrypted using a Caesar Cipher. What is - its secret number? + its secret number? 1 2. `secrets/secret2.txt` is encrypted using a Caesar Cipher. What is - its secret number? + its secret number? 44 3. `secrets/secret3.txt` is encrypted using a Caesar Cipher. What is - its secret number? + its secret number? 59 4. `secrets/secret4.txt` is encrypted using a Caesar Cipher. What is - its secret number? + its secret number? 32 ## Checkpoint 2 -5. What is the polyalphabetic secret word? +5. What is the polyalphabetic secret word? supersecret 6. Decrypt this message, which was encrypted using the same secret word: "EbZhdaV[h^bTpchhQnhig]X[VmhhRP]ftXVnRfjVY]fgtO_X](" +answer: Cryptography is the practice and study of techniques for secure communication. \ No newline at end of file diff --git a/caesar_cracker.py b/caesar_cracker.py index 471ee8c..6a8cfb9 100644 --- a/caesar_cracker.py +++ b/caesar_cracker.py @@ -1,13 +1,11 @@ from collections import Counter +from easybits import Bits def crack_caesar(ciphertext): + counts = Counter(ciphertext) - counts = Counter(ciphertext.upper()) + most_common = counts.most_common(1)[0][0] - most_common_letter = counts.most_common(1)[0][0] + shift = Bits(most_common).int - Bits(' ').int - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - - shift = (alphabet.index(most_common_letter) - alphabet.index("E")) % 26 - - return shift \ No newline at end of file + return shift diff --git a/caesar_cracker.py.save b/caesar_cracker.py.save new file mode 100644 index 0000000..15fbe56 --- /dev/null +++ b/caesar_cracker.py.save @@ -0,0 +1,13 @@ +from collections import Counter + +def crack_caesar(ciphertext): + + counts = Counter(ciphertext.upper()) + + most_common_letter = counts.most_common(1)[0][0] + + alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + shift = (alphabet.index(most_common_letter) - alphabet.index("E")) % 26 + + return shift diff --git a/easybits.py b/easybits.py new file mode 100644 index 0000000..7a2b556 --- /dev/null +++ b/easybits.py @@ -0,0 +1,21 @@ +class Bits: + def __init__(self, value, encoding='ascii', length=None): + if isinstance(value, str): + self.int = ord(value) + elif isinstance(value, int): + self.int = value % 128 # ⚠️ change to 128 (ASCII range) + else: + raise TypeError("Unsupported type") + + @property + def ascii(self): + return chr(self.int) + + def __add__(self, other): + return Bits((self.int + other.int) % 128) + + def __sub__(self, other): + return Bits((self.int - other.int) % 128) + + def __repr__(self): + return f"Bits({self.int})"