Skip to content

Instantly share code, notes, and snippets.

@Timo614
Last active June 6, 2025 21:10
Show Gist options
  • Save Timo614/d06a4cdab7d9ad3e89e6a2668f181a1e to your computer and use it in GitHub Desktop.
Save Timo614/d06a4cdab7d9ad3e89e6a2668f181a1e to your computer and use it in GitHub Desktop.
kryptos-k1-k3.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/Timo614/d06a4cdab7d9ad3e89e6a2668f181a1e/kryptos-k1-k3.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"source": [
"\n",
"import sys\n",
"\n",
"MORSE_CODE_DICT = {\n",
" \".-\": \"A\", \"-...\": \"B\", \"-.-.\": \"C\", \"-..\": \"D\", \".\": \"E\",\n",
" \"..-.\": \"F\", \"--.\": \"G\", \"....\": \"H\", \"..\": \"I\", \".---\": \"J\",\n",
" \"-.-\": \"K\", \".-..\": \"L\", \"--\": \"M\", \"-.\": \"N\", \"---\": \"O\",\n",
" \".--.\": \"P\", \"--.-\": \"Q\", \".-.\": \"R\", \"...\": \"S\", \"-\": \"T\",\n",
" \"..-\": \"U\", \"...-\": \"V\", \".--\": \"W\", \"-..-\": \"X\", \"-.--\": \"Y\",\n",
" \"--..\": \"Z\",\n",
" \"-----\": \"0\", \".----\": \"1\", \"..---\": \"2\", \"...--\": \"3\", \"....-\": \"4\",\n",
" \".....\": \"5\", \"-....\": \"6\", \"--...\": \"7\", \"---..\": \"8\", \"----.\": \"9\",\n",
" \".-.-.-\": \".\", \"--..--\": \",\", \"..--..\": \"?\", \".----.\": \"'\",\n",
" \"-.-.--\": \"!\", \"-..-.\": \"/\", \"-.--.\": \"(\", \"-.--.-\": \")\",\n",
" \".-...\": \"&\", \"---...\": \":\", \"-.-.-.\": \";\", \"-...-\": \"=\",\n",
" \".-.-.\": \"+\", \"-....-\": \"-\", \"..--.-\": \"_\", \".-..-.\": \"\\\"\",\n",
" \"...-..-\": \"$\", \".--.-.\": \"@\",\n",
" \"...---...\": \"SOS\"\n",
"}\n",
"\n",
"def normalize_morse_string(raw_string):\n",
" unicode_dots = [\"\\u00B7\", \"\\u22C5\", \"\\u2022\", \"\\u2219\"]\n",
" unicode_dashes = [\"\\u2013\", \"\\u2014\", \"\\u2212\"]\n",
" normalized_chars = []\n",
" for ch in raw_string:\n",
" if ch in unicode_dots:\n",
" normalized_chars.append(\".\")\n",
" elif ch in unicode_dashes:\n",
" normalized_chars.append(\"-\")\n",
" else:\n",
" normalized_chars.append(ch)\n",
" return \"\".join(normalized_chars)\n",
"\n",
"def decode_morse_letter(pattern, morse_dict, unknown_patterns):\n",
" if pattern in morse_dict:\n",
" return morse_dict[pattern]\n",
" else:\n",
" unknown_patterns.append(pattern)\n",
" return \"?\"\n",
"\n",
"def decode_full_morse_string(morse_string, morse_dict):\n",
" unknown_patterns = []\n",
" decoded_lines = []\n",
" for line in morse_string.split(\"\\n\"):\n",
" words = line.split(\"\\t\")\n",
" decoded_words = []\n",
" for word_chunk in words:\n",
" word_chunk = word_chunk.strip()\n",
" if not word_chunk:\n",
" continue\n",
" letter_patterns = word_chunk.split(\" \")\n",
" decoded_letters = []\n",
" for pat in letter_patterns:\n",
" pat = pat.strip()\n",
" if not pat:\n",
" continue\n",
" decoded_char = decode_morse_letter(pat, morse_dict, unknown_patterns)\n",
" decoded_letters.append(decoded_char)\n",
" decoded_words.append(\"\".join(decoded_letters))\n",
" decoded_lines.append(\" \".join(decoded_words))\n",
" decoded_text = \"\\n\".join(decoded_lines)\n",
" return decoded_text, unknown_patterns\n",
"\n",
"if __name__ == \"__main__\":\n",
" RAW_MORSE_SEGMENTS = [\n",
" \"· · ···- ·· ·-· – ··- ·- ·-·· ·-·· -.-- · \\t · · · · · · ·· -· ···- ·· ··· ·· -··· ·-·· ·\",\n",
" \". -.. .. --. . - .- .-.. . . . \\t .. -. - . .-. .--. .-. . - .- - .. -\",\n",
" \". . ... .... .- -.. --- .-- . . \\t ..-. --- .-. -.-. . ... . . . . .\",\n",
" \".-.. ..- -.-. .. -.. . . . \\t -- . -- --- .-. -.-- .\",\n",
" \"- .. ... -.-- --- ..- .-. \\t .--. --- ... .. - .. --- -. .\",\n",
" \".-. --.-\",\n",
" \"...---...\"\n",
" ]\n",
" RAW_MORSE_INPUT = \"\\t\\n\".join(RAW_MORSE_SEGMENTS)\n",
" normalized = normalize_morse_string(RAW_MORSE_INPUT)\n",
" decoded_text, unknowns = decode_full_morse_string(normalized, MORSE_CODE_DICT)\n",
" print(normalized)\n",
" print(decoded_text)"
],
"metadata": {
"id": "jcGHKIz2-pHS",
"outputId": "574cbd61-da9a-4a9b-96cc-60e9422b319c",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
". . ...- .. .-. - ..- .- .-.. .-.. -.-- . \t . . . . . . .. -. ...- .. ... .. -... .-.. .\t\n",
". -.. .. --. . - .- .-.. . . . \t .. -. - . .-. .--. .-. . - .- - .. -\t\n",
". . ... .... .- -.. --- .-- . . \t ..-. --- .-. -.-. . ... . . . . .\t\n",
".-.. ..- -.-. .. -.. . . . \t -- . -- --- .-. -.-- .\t\n",
"- .. ... -.-- --- ..- .-. \t .--. --- ... .. - .. --- -. .\t\n",
".-. --.-\t\n",
"...---...\n",
"EEVIRTUALLYE EEEEEEINVISIBLE\n",
"EDIGETALEEE INTERPRETATIT\n",
"EESHADOWEE FORCESEEEEE\n",
"LUCIDEEE MEMORYE\n",
"TISYOUR POSITIONE\n",
"RQ\n",
"SOS\n"
]
}
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "pCQtN7AstLj5"
},
"outputs": [],
"source": [
"import string\n",
"import re\n",
"import math\n",
"from collections import OrderedDict, Counter\n",
"from enum import Enum\n",
"from typing import List, Dict, Tuple\n",
"\n",
"class Vigenere:\n",
" @staticmethod\n",
" def generate_table(alphabet: str) -> Tuple[List[str], List[int]]:\n",
" seen = set()\n",
" keyword_chars = []\n",
" for c in alphabet:\n",
" uc = c.upper()\n",
" if 'A' <= uc <= 'Z' and uc not in seen:\n",
" seen.add(uc)\n",
" keyword_chars.append(uc)\n",
" # 2) Fill out to full A–Z\n",
" for letter in string.ascii_uppercase:\n",
" if letter not in seen:\n",
" keyword_chars.append(letter)\n",
" seen.add(letter)\n",
" # 3) Create lookup: letter → index in keyword array\n",
" keyword_array = keyword_chars[:26]\n",
" abc_lookup_table = [0] * 26\n",
" for idx, letter in enumerate(keyword_array):\n",
" abc_lookup_table[ord(letter) - 65] = idx\n",
" return keyword_array, abc_lookup_table\n",
"\n",
" @staticmethod\n",
" def generate_codex(abc_lookup_table: List[int], keyword: str) -> List[int]:\n",
" \"\"\"\n",
" Turn each char of 'keyword' into its index in the table.\n",
" \"\"\"\n",
" codex = []\n",
" for letter in keyword:\n",
" uc = letter.upper()\n",
" if 'A' <= uc <= 'Z':\n",
" codex.append(abc_lookup_table[ord(uc) - 65])\n",
" return codex\n",
"\n",
" def __init__(self, alphabet: str, keyword: str):\n",
" self.keyword_array, self.abc_lookup_table = self.generate_table(alphabet)\n",
" self.codex = self.generate_codex(self.abc_lookup_table, keyword)\n",
"\n",
" def decrypt(self, ciphertext: str) -> str:\n",
" result = []\n",
" idx = 0\n",
" codex_len = len(self.codex)\n",
" for c in ciphertext:\n",
" if c.isalpha():\n",
" uc = c.upper()\n",
" shift = self.codex[idx % codex_len]\n",
" base_idx = self.abc_lookup_table[ord(uc) - 65]\n",
" dec_idx = (26 + base_idx - shift) % 26\n",
" result.append(self.keyword_array[dec_idx])\n",
" idx += 1\n",
" else:\n",
" result.append(c)\n",
" return ''.join(result)\n",
"\n",
" def encrypt_with_index(self, plaintext: str, codex_start: int) -> str:\n",
" \"\"\"\n",
" Standard Vigenère encryption but allowing a nonzero initial position\n",
" in the repeating key (codex).\n",
" \"\"\"\n",
" result = []\n",
" codex_idx = codex_start % len(self.codex)\n",
" for c in plaintext:\n",
" if c.isalpha():\n",
" uc = c.upper()\n",
" # find plaintext letter in keyword_array\n",
" kw_idx = self.keyword_array.index(uc)\n",
" enc_idx = (self.codex[codex_idx] + kw_idx) % 26\n",
" result.append(self.keyword_array[enc_idx])\n",
" codex_idx = (codex_idx + 1) % len(self.codex)\n",
" else:\n",
" result.append(c)\n",
" return ''.join(result)\n",
"\n",
" def encrypt(self, plaintext: str) -> str:\n",
" \"\"\"Encrypt starting at codex index 0.\"\"\"\n",
" return self.encrypt_with_index(plaintext, 0)\n",
"\n",
"\n",
"def apply_pattern(text: str, pattern: List[int]) -> str:\n",
" \"\"\"\n",
" Shift the entire alphabet by each integer in 'pattern' in sequence,\n",
" then apply that final mapping to 'text'.\n",
" \"\"\"\n",
" alphabet = string.ascii_uppercase\n",
" shifted = alphabet\n",
" mapping = {}\n",
" for shift in pattern:\n",
" s = shift % 26\n",
" shifted = shifted[s:] + shifted[:s]\n",
" mapping = {alphabet[i]: shifted[i] for i in range(26)}\n",
" # map only uppercase letters; leave others untouched\n",
" return ''.join(mapping.get(c.upper(), c) if c.isalpha() else c for c in text)\n",
"\n",
"\n",
"def generate_plaintext_letter_mapping() -> Dict[str, Dict[str, str]]:\n",
" \"\"\"\n",
" Build mapping: plaintext_letter → (encrypted_letter → key_letter)\n",
" using Vigenère keyed off 'KRYPTOS'.\n",
" \"\"\"\n",
" mapping: Dict[str, Dict[str, str]] = {}\n",
" for plain in string.ascii_uppercase:\n",
" inner = {}\n",
" for key_char in string.ascii_uppercase:\n",
" vig = Vigenere(\"KRYPTOS\", key_char)\n",
" enc = vig.encrypt(plain)\n",
" inner[enc] = key_char\n",
" mapping[plain] = inner\n",
" return mapping\n",
"\n",
"\n",
"def find_shift_keys(encrypted_text: str, plaintext: str) -> OrderedDict:\n",
" \"\"\"\n",
" For each Caesar shift 0–25, unshift the encrypted text and\n",
" derive the Vigenère key stream that maps unshifted→plaintext.\n",
" \"\"\"\n",
" pt_map = generate_plaintext_letter_mapping()\n",
" results = OrderedDict()\n",
" for shift in range(26):\n",
" shifted_enc = apply_pattern(encrypted_text, [-shift])\n",
" key_text = ''.join(\n",
" pt_map.get(p, {}).get(e, '')\n",
" for e, p in zip(shifted_enc, plaintext)\n",
" )\n",
" results[shift] = key_text\n",
" return results\n",
"\n",
"\n",
"def find_pre_shift_keys(encrypted_text: str, plaintext: str) -> OrderedDict:\n",
" \"\"\"\n",
" Similar to above but shift the plaintext first, then compare.\n",
" \"\"\"\n",
" pt_map = generate_plaintext_letter_mapping()\n",
" results = OrderedDict()\n",
" for shift in range(26):\n",
" shifted_plain = apply_pattern(plaintext, [-shift])\n",
" key_text = ''.join(\n",
" pt_map.get(sp, {}).get(ec, '')\n",
" for ec, sp in zip(encrypted_text, shifted_plain)\n",
" )\n",
" results[shift] = key_text\n",
" return results\n",
"\n",
"class Direction(Enum):\n",
" Right = 1\n",
" Left = 2\n",
"\n",
"class Shift:\n",
" def __init__(self, column_size: int, rotation_direction: Direction):\n",
" self.column_size = column_size\n",
" self.rotation_direction = rotation_direction\n",
"\n",
"def transpose(mat: List[List[str]]) -> List[List[str]]:\n",
" max_cols = max(len(row) for row in mat)\n",
" return [\n",
" [row[i] if i < len(row) else ' ' for row in mat]\n",
" for i in range(max_cols)\n",
" ]\n",
"\n",
"def transform_text(\n",
" text: str, column_width: int, rotation_direction: Direction\n",
") -> str:\n",
" padding = (column_width - len(text) % column_width) % column_width\n",
" if rotation_direction == Direction.Right:\n",
" chars = list(text) + ['\\0'] * padding\n",
" chunks = [chars[i:i+column_width] for i in range(0, len(chars), column_width)]\n",
" else:\n",
" inverse = math.ceil(len(text) / column_width)\n",
" sep = inverse * (column_width - padding)\n",
" part1 = text[:sep]\n",
" part2 = text[sep:]\n",
" chunks = [list(part1[i:i+inverse]) for i in range(0, len(part1), inverse)]\n",
" for i in range(0, len(part2), inverse-1):\n",
" chunk = list(part2[i:i+(inverse-1)])\n",
" chunk.insert(0, '\\0')\n",
" chunks.append(chunk)\n",
" trans = transpose(chunks)\n",
" cols = [''.join(reversed(r)) for r in trans]\n",
" combined = ''.join(cols)\n",
" if rotation_direction == Direction.Left:\n",
" combined = combined[::-1]\n",
" return ''.join(c for c in combined if c.isalpha())\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "eIlxlFFgvmWS",
"outputId": "a3b8b3e1-5f4c-41f5-d9a0-f60ff054bd22"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFD\n"
]
}
],
"source": [
"plaintext = \"BETWEENSUBTLESHADINGANDTHEABSENCEOFLIGHTLIESTHENUANCEOFIQLUSION\"\n",
"cipher = Vigenere(\"KRYPTOS\", \"PALIMPSEST\")\n",
"encoded = cipher.encrypt(plaintext)\n",
"print(encoded)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jNryUnQuwI5V",
"outputId": "6f01079f-e52f-43e5-f3e0-ae9f7ca8e002"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Decrypted text: BETWEENSUBTLESHADINGANDTHEABSENCEOFLIGHTLIESTHENUANCEOFIQLUSION\n"
]
}
],
"source": [
"ciphertext = \"EMUFPHZLRFAXYUSDJKZLDKRNSHGNFIVJYQTQUXQBQVYUVLLTREVJYQTMKYRDMFD\"\n",
"cipher = Vigenere(\"KRYPTOS\", \"PALIMPSEST\")\n",
"decoded = cipher.decrypt(ciphertext)\n",
"print(\"Decrypted text:\", decoded)"
]
},
{
"cell_type": "code",
"source": [
"plaintext = \"ITWASTOTALLYINVISIBLEHOWSTHATPOSSIBLE?THEYUSEDTHEEARTHSMAGNETICFIELDXTHEINFORMATIONWASGATHEREDANDTRANSMITTEDUNDERGRUUNDTOANUNKNOWNLOCATIONXDOESLANGLEYKNOWABOUTTHIS?THEYSHOULDITSBURIEDOUTTHERESOMEWHEREXWHOKNOWSTHEEXACTLOCATION?ONLYWWTHISWASHISLASTMESSAGEXTHIRTYEIGHTDEGREESFIFTYSEVENMINUTESSIXPOINTFIVESECONDSNORTHSEVENTYSEVENDEGREESEIGHTMINUTESFORTYFOURSECONDSWESTXLAYERTWO\"\n",
"cipher = Vigenere(\"KRYPTOS\", \"ABSCISSA\")\n",
"encoded = cipher.encrypt(plaintext)\n",
"print(encoded)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "X05onQVdLbya",
"outputId": "ff256c9c-0d15-4907-f3c9-ca0b7e4873ee"
},
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"VFPJUDEEHZWETZYVGWHKKQETGFQJNCEGGWHKK?DQMCPFQZDQMMIAGPFXHQRLGTIMVMZJANQLVKQEDAGDVFRPJUNGEUNAQZGZLECGYUXUEENJTBJLBQCRTBJDFHRRYIZETKZEMVDUFKSJHKFWHKUWQLSZFTIHHDDDUVH?DWKBFUFPWNTDFIYCUQZEREEVLDKFEZMOQQJLTTUGSYQPFEUNLAVIDXFLGGTEZ?FKZBSFDQVGOGIPUFXHHDRKFFHQNTGPUAECNUVPDJMQCLQUMUNEDFQELZZVRRGKFFVOEEXBDMVPNFQXEZLGREDNQFMPNZGLFLPMRJQYALMGNUVPDXVKPDQUMEBEDMHDAFMJGZNUPLGESWJLLAETG\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"ciphertext = \"VFPJUDEEHZWETZYVGWHKKQETGFQJNCEGGWHKK?DQMCPFQZDQMMIAGPFXHQRLGTIMVMZJANQLVKQEDAGDVFRPJUNGEUNAQZGZLECGYUXUEENJTBJLBQCRTBJDFHRRYIZETKZEMVDUFKSJHKFWHKUWQLSZFTIHHDDDUVH?DWKBFUFPWNTDFIYCUQZEREEVLDKFEZMOQQJLTTUGSYQPFEUNLAVIDXFLGGTEZ?FKZBSFDQVGOGIPUFXHHDRKFFHQNTGPUAECNUVPDJMQCLQUMUNEDFQELZZVRRGKFFVOEEXBDMVPNFQXEZLGREDNQFMPNZGLFLPMRJQYALMGNUVPDXVKPDQUMEBEDMHDAFMJGZNUPLGEWJLLAETG\"\n",
"cipher = Vigenere(\"KRYPTOS\", \"ABSCISSA\")\n",
"decoded = cipher.decrypt(ciphertext)\n",
"print(\"Decrypted text:\", decoded)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "UHsVKujELb14",
"outputId": "d06fe4f5-1617-4837-d62a-37cd46252af8"
},
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Decrypted text: ITWASTOTALLYINVISIBLEHOWSTHATPOSSIBLE?THEYUSEDTHEEARTHSMAGNETICFIELDXTHEINFORMATIONWASGATHEREDANDTRANSMITTEDUNDERGRUUNDTOANUNKNOWNLOCATIONXDOESLANGLEYKNOWABOUTTHIS?THEYSHOULDITSBURIEDOUTTHERESOMEWHEREXWHOKNOWSTHEEXACTLOCATION?ONLYWWTHISWASHISLASTMESSAGEXTHIRTYEIGHTDEGREESFIFTYSEVENMINUTESSIXPOINTFIVESECONDSNORTHSEVENTYSEVENDEGREESEIGHTMINUTESFORTYFOURSECONDSWESTIDBYROWS\n"
]
}
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "L-Tjj0oow1Dh",
"outputId": "ccb69ca2-a812-4af9-b596-3bd362b6dc44"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"=== find_shift_keys ===\n",
"Shift= 0 → PALIMPSEST\n",
"Shift= 1 → YSKHQYCQZP\n",
"Shift= 2 → RIYGBRODBY\n",
"Shift= 3 → KOWFAKTCDR\n",
"Shift= 4 → ZTJESZPBXK\n",
"Shift= 5 → LPZDIXYAWZ\n",
"Shift= 6 → QYRYOWESVL\n",
"Shift= 7 → JRIOTVGOOQ\n",
"Shift= 8 → IKHRPHBTUJ\n",
"Shift= 9 → HZGKYLRPQI\n",
"Shift=10 → GXVZRGDYNH\n",
"Shift=11 → VWFXKFFRMG\n",
"Shift=12 → XVEAZEKNLV\n",
"Shift=13 → NHDCXDZVJX\n",
"Shift=14 → FLCTWNXMIN\n",
"Shift=15 → UGBWVUALHF\n",
"Shift=16 → WFASHJWJGU\n",
"Shift=17 → EESBLCVIFW\n",
"Shift=18 → DDOVGMUXTE\n",
"Shift=19 → CNTUFQQKAD\n",
"Shift=20 → MUPQEBNUPC\n",
"Shift=21 → BJUPDAMHYM\n",
"Shift=22 → ACXNNSLWRB\n",
"Shift=23 → SMQMUIJZKA\n",
"Shift=24 → OQNLJOIGCS\n",
"Shift=25 → TBMJCTHFEO\n",
"\n",
"=== find_pre_shift_keys ===\n",
"Shift= 0 → PALIMPSEST\n",
"Shift= 1 → TBIJNTAJWO\n",
"Shift= 2 → FCQLQOBWUG\n",
"Shift= 3 → CDRBUSZHKD\n",
"Shift= 4 → GEMSVACFAH\n",
"Shift= 5 → HNJETIDXXI\n",
"Shift= 6 → IJYMRFEZVJ\n",
"Shift= 7 → JQPCOJFKBL\n",
"Shift= 8 → AUTASLGLCB\n",
"Shift= 9 → OVUNAMHRDS\n",
"Shift=10 → DWOQBNIYRE\n",
"Shift=11 → LHSUZDJPEM\n",
"Shift=12 → BFAFWBLTFC\n",
"Shift=13 → SLBVYGMOGA\n",
"Shift=14 → MXCWCQKSHN\n",
"Shift=15 → NIDXKEWAIQ\n",
"Shift=16 → QGEZXCRBJU\n",
"Shift=17 → EZFKDUYCLF\n",
"Shift=18 → UKGREVPDMV\n",
"Shift=19 → VRHYFWTMNW\n",
"Shift=20 → WMVPPHUIQX\n",
"Shift=21 → XYNTGXNNYZ\n",
"Shift=22 → ZPWOHZXQZK\n",
"Shift=23 → KTXGIKOUPR\n",
"Shift=24 → ROZDJRVVTY\n",
"Shift=25 → YSKHLYQGOP\n"
]
}
],
"source": [
"encrypted = \"EMUFPHZLRF\"\n",
"plaintext = \"BETWEENSUB\"\n",
"\n",
"shift_keys = find_shift_keys(encrypted, plaintext)\n",
"print(\"=== find_shift_keys ===\")\n",
"for shift, keystream in shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")\n",
"\n",
"pre_shift_keys = find_pre_shift_keys(encrypted, plaintext)\n",
"print(\"\\n=== find_pre_shift_keys ===\")\n",
"for shift, keystream in pre_shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "-KSu_bELxHBx",
"outputId": "a90a1678-3f3d-45fd-c52c-70cf897ef8d1"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Encode matches expected: True\n",
"Decode matches original: True\n"
]
}
],
"source": [
"plaintext = (\n",
" \"SLOWLYDESPARATLYSLOWLYTHEREMAINSOFPASSAGED\"\n",
" \"EBRISTHATENCUMBEREDTHELOWERPARTOFTHEDOORWA\"\n",
" \"YWASREMOVEDWITHTREMBLINGHANDSIMADEATINYBRE\"\n",
" \"ACHINTHEUPPERLEFTHANDCORNERANDTHENWIDENING\"\n",
" \"THEHOLEALITTLEIINSERTEDTHECANDLEANDPEEREDI\"\n",
" \"NTHEHOTAIRESCAPINGFROMTHECHAMBERCAUSEDTHEF\"\n",
" \"LAMETOFLICKERBUTPRESENTLYDETAILSOFTHEROOMW\"\n",
" \"ITHINEMERGEDFROMTHEMISTXCANYOUSEEANYTHINGQ\"\n",
")\n",
"\n",
"ciphertext = (\n",
" \"ENDYAHROHNLSRHEOCPTEOIBIDYSHNAIACHTNREYULDSLLSLLNOHSNOSMRWXMNE\"\n",
" \"TPRNGATIHNRARPESLNNELEBLPIIACAEWMTWNDITEENRAHCTENEUDRETNHAEOE\"\n",
" \"TFOLSEDTIWENHAEIOYTEYQHEENCTAYCREIFTBRSPAMHHEWENATAMATEGYEERLB\"\n",
" \"TEEFOASFIOTUETUAEOTOARMAEERTNRTIBSEDDNIAAHTTMSTEWPIEROAGRIEWFEB\"\n",
" \"AECTDDHILCEIHSITEGOEAOSDDRYDLORITRKLMLEHAGTDHARDPNEOHMGFMFEUHE\"\n",
" \"ECDMRIPFEIMEHNLSSTTRTVDOHW\"\n",
")\n",
"\n",
"step1 = transform_text(plaintext, 42, Direction.Right)\n",
"calc_cipher = transform_text(step1, 14, Direction.Right)\n",
"print(\"Encode matches expected:\", calc_cipher == ciphertext)\n",
"\n",
"step1_dec = transform_text(ciphertext, 14, Direction.Left)\n",
"decoded = transform_text(step1_dec, 42, Direction.Left)\n",
"print(\"Decode matches original:\", decoded == plaintext)\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "S21Ma_vjyyKt",
"outputId": "114a72bd-c4bf-4a74-e996-ad96f507a86e"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"EASTNORTHEAST\n",
"=== find_shift_keys ===\n",
"Shift= 0 → RDUMRIYWOYNKY\n",
"Shift= 1 → KNHLDXTJTRCUW\n",
"Shift= 2 → ZCWKFKMZPKBHJ\n",
"Shift= 3 → XBZYKHLRFZAWZ\n",
"Shift= 4 → WAGWZGJIYXSZR\n",
"Shift= 5 → VSFJXFZHRWOGI\n",
"Shift= 6 → HOEZAUIGKVTFH\n",
"Shift= 7 → LTQRWEHVZHPEG\n",
"Shift= 8 → GPDIVDGFXLYQV\n",
"Shift= 9 → FYCHUCFEWGRDF\n",
"Shift=10 → ERBGQBEDVFKCE\n",
"Shift=11 → DKAVNADCUEMBD\n",
"Shift=12 → NMSFMSCBQDUAC\n",
"Shift=13 → UUOELOBANNLSB\n",
"Shift=14 → JLTDJTASEUJOA\n",
"Shift=15 → CJPCIPSOHJITS\n",
"Shift=16 → MIYBHYXTDCHPO\n",
"Shift=17 → QHRASQRPCMWYT\n",
"Shift=18 → BWNSCWWUBQZRP\n",
"Shift=19 → AZVOONVXABQNU\n",
"Shift=20 → SQMTTMUQJAGVX\n",
"Shift=21 → IGLPPLQNMSVMQ\n",
"Shift=22 → OVJUYJPMGIXLN\n",
"Shift=23 → TXIXEZOLSOFJM\n",
"Shift=24 → PFXQGRKKITEIL\n",
"Shift=25 → YEKNBVNYLPDXK\n",
"\n",
"=== find_pre_shift_keys ===\n",
"Shift= 0 → RDUMRIYWOYNKY\n",
"Shift= 1 → YMKJYRCUSPROK\n",
"Shift= 2 → PIAUPYKKATXFO\n",
"Shift= 3 → TNXYQPXABOYPF\n",
"Shift= 4 → OQVNTQDXCSPRP\n",
"Shift= 5 → GUBLOTEVDHTGR\n",
"Shift= 6 → DVCPSOFBEEOHG\n",
"Shift= 7 → HGDTASPCFIVIH\n",
"Shift= 8 → IEROBAGDQJQSI\n",
"Shift= 9 → JJEVCBHRLLZJS\n",
"Shift=10 → LWFSDCIEUMSLJ\n",
"Shift=11 → BHGAEDJFVCWML\n",
"Shift=12 → SFHBFELGWAUNM\n",
"Shift=13 → EXICGFMHXFAQN\n",
"Shift=14 → MZJDUGNIINBUQ\n",
"Shift=15 → CKLEMUQJGDCVU\n",
"Shift=16 → ALMFVMULMBKWV\n",
"Shift=17 → NRNGWVVMZQDXW\n",
"Shift=18 → QYQHXWTNJUEZX\n",
"Shift=19 → UPYIZXRQHVFAZ\n",
"Shift=20 → FTZWJZOYKGGTA\n",
"Shift=21 → VOPQHJSZRWHBT\n",
"Shift=22 → WSTXNHAPYXICB\n",
"Shift=23 → XAOZKNBTNZJDC\n",
"Shift=24 → ZBSKLKZOPKLED\n",
"Shift=25 → KCWRILWSTRMYE\n",
"\n",
"\n",
"BERLINCLOCK\n",
"=== find_shift_keys ===\n",
"Shift= 0 → ELYOIECBAQK\n",
"Shift= 1 → DGTTLGBESVJ\n",
"Shift= 2 → CFMGFBLAODI\n",
"Shift= 3 → MELIORASTCH\n",
"Shift= 4 → BDJDHDSOPBG\n",
"Shift= 5 → ANZPJFOTYLF\n",
"Shift= 6 → SUIFTKTGQAE\n",
"Shift= 7 → OJHHPZPIWSD\n",
"Shift= 8 → TCGYYXYDNOC\n",
"Shift= 9 → PMFREARPMTB\n",
"Shift=10 → YQEKRWKFLPA\n",
"Shift=11 → RBDCKVZHJYZ\n",
"Shift=12 → KACZZUXYZRY\n",
"Shift=13 → ZSBXXQJRRKX\n",
"Shift=14 → LIAWWNNKVZW\n",
"Shift=15 → QOSVVMICIXV\n",
"Shift=16 → JTXUULHZXJU\n",
"Shift=17 → IPRQQJGXKNT\n",
"Shift=18 → HYWNNIFWHIS\n",
"Shift=19 → GRVMMHUVGHR\n",
"Shift=20 → VKULDSWUFGQ\n",
"Shift=21 → XZQJGCMQUFP\n",
"Shift=22 → NXPBCOENEUO\n",
"Shift=23 → FWOEBTQMDWN\n",
"Shift=24 → UVKAAPVLCMM\n",
"Shift=25 → WHNSSYDJBEL\n",
"\n",
"=== find_pre_shift_keys ===\n",
"Shift= 0 → ELYOIECBAQK\n",
"Shift= 1 → FMCVJFDZNUD\n",
"Shift= 2 → QNKSLGECQVE\n",
"Shift= 3 → LQXAMTNDUTF\n",
"Shift= 4 → UUDBNHJEFRG\n",
"Shift= 5 → VPECQIQFVOH\n",
"Shift= 6 → WKFDUJUGWSI\n",
"Shift= 7 → XTPEVLVHXAJ\n",
"Shift= 8 → IOGFWMWIZBL\n",
"Shift= 9 → GSHGONHJKZM\n",
"Shift=10 → MAIHYQFLRWN\n",
"Shift=11 → ZXJISULMYYR\n",
"Shift=12 → JVLWAVXKPCX\n",
"Shift=13 → HRMQBWIWTKY\n",
"Shift=14 → KBNXCOGROXP\n",
"Shift=15 → RZQZKYZYGDT\n",
"Shift=16 → YWUKXSKPDEO\n",
"Shift=17 → NCVRPARTHFV\n",
"Shift=18 → PDTMDBMUIPQ\n",
"Shift=19 → TERJRCYNJGZ\n",
"Shift=20 → OYOUZKPXLHS\n",
"Shift=21 → SFSYEXTOBIW\n",
"Shift=22 → AGANFPOVSJU\n",
"Shift=23 → BHBLGDSQELA\n",
"Shift=24 → CIZPTRASMMB\n",
"Shift=25 → DJWTHZBACNC\n"
]
}
],
"source": [
"encrypted = \"FLRVQQPRNGKSS\"\n",
"plaintext = \"EASTNORTHEAST\"\n",
"print(plaintext)\n",
"\n",
"shift_keys = find_shift_keys(encrypted, plaintext)\n",
"print(\"=== find_shift_keys ===\")\n",
"for shift, keystream in shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")\n",
"\n",
"pre_shift_keys = find_pre_shift_keys(encrypted, plaintext)\n",
"print(\"\\n=== find_pre_shift_keys ===\")\n",
"for shift, keystream in pre_shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")\n",
"\n",
"encrypted = \"NYPVTTMZFPK\"\n",
"plaintext = \"BERLINCLOCK\"\n",
"\n",
"print(\"\\n\")\n",
"print(plaintext)\n",
"shift_keys = find_shift_keys(encrypted, plaintext)\n",
"print(\"=== find_shift_keys ===\")\n",
"for shift, keystream in shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")\n",
"\n",
"pre_shift_keys = find_pre_shift_keys(encrypted, plaintext)\n",
"print(\"\\n=== find_pre_shift_keys ===\")\n",
"for shift, keystream in pre_shift_keys.items():\n",
" print(f\"Shift={shift:2d} → {keystream}\")\n",
"\n"
]
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "DE7RNlMQRy-M"
},
"execution_count": null,
"outputs": []
}
],
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyNo6RZszLovhoWEMSdePX4W",
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment