Done challenge 8
authorNeil Smith <neil.git@njae.me.uk>
Fri, 3 Dec 2021 09:35:52 +0000 (09:35 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 3 Dec 2021 09:35:52 +0000 (09:35 +0000)
2021/2021-challenge7.ipynb
2021/2021-challenge7.md
2021/2021-challenge8.ipynb [new file with mode: 0644]
2021/2021-challenge8.md [new file with mode: 0644]
2021/ciphertext.8a.txt [new file with mode: 0644]
2021/ciphertext.8b.txt [new file with mode: 0644]
2021/plaintext.8a.txt [new file with mode: 0644]

index 967060aa31194035c50705f2cddf062d70d526c1..089f6806359ebfc6529ab4c59d6ec344253421ae 100644 (file)
@@ -43,7 +43,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 3,
    "id": "0f1f792a",
    "metadata": {
     "Collapsed": "false"
@@ -64,7 +64,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 4,
    "id": "b8d5f9ec-27f1-498b-8e64-c5eb2424e581",
    "metadata": {},
    "outputs": [
@@ -74,7 +74,7 @@
        "Counter({'e': 632, 'c': 619, 'a': 714, 'b': 410, 'd': 787})"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 4,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -86,7 +86,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 5,
    "id": "b5cabba1-ac75-46ea-ac05-8699cc88d986",
    "metadata": {},
    "outputs": [
@@ -96,7 +96,7 @@
        "<AxesSubplot:>"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 5,
      "metadata": {},
      "output_type": "execute_result"
     },
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 6,
    "id": "583312cf-a973-4671-9ba8-85fe10cb9e00",
    "metadata": {},
    "outputs": [
        " -6776.263168839725)"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 7,
    "id": "4262216b-efed-491e-ade1-d7e8dffe4454",
    "metadata": {},
    "outputs": [
        "'wemounhtbeattacbehkessayebdhhendntbeunherizdnycoheomandkayesentdnfungkaditopeopieattbeuseklasszdtkdybtbavesidppehpastuslutiucgdizbarrzanhdbahaireahzmdyurehouttbattbezkdybttrztocokkundcatetbdswaztbeconspdraczbahavodhehhetectdonmoroveracenturzsotbezwereunidgeiztokagetbekdstageomsenhdnykessayesexpidcdtizahhressehtooneanotberdtdsaiwazslestnottokageidngsletweenkeklersomanetworganhaweiibdhhenkessayednfungkadiavodhstbatrdsgespecdaiizdmdtdswdheizhdstrdlutehlzoneomtbelotnetworgsidgetbdsonedwastoomocussehontbehecrzptatmdrstanhwasntreahdnywbatdtsadhuntdidmounhbernakestardnylacgatkeattbeenhperbapswesbouihbaveaireahzreaidsehtbattrdndtzcouihlednvoivehlutdtneveroccurrehtoketbatbernakewasanztbdnyotbertbanacodncdhencetbemactsbescbaridesndecesbouihbaveidtuptbeidybtsontbehasbloarhtbouybanhdakworrdehtbatbarrzhdhntradsedtperbapsbedsaireahzsbahowdnyberanhhdhntidgetosazsooutomiozaitzlutbehdhntteiiketbatanhsokebowdtbdngbewouihdtbdngdtskoreidgeiztbatsbeslezonhsuspdcdondnbdskdnhsbebaspiazehandkportantroiednbdsnetworgmormourteenzearsanhtbemacttbatsbekdybtleahoulieayentwdiileareailiowtbatwaslahlutdtwasnttbeworstomdttbehetaditrdndtzydvesontbeconspdraczsrecentactdvdtdesdstruizmrdybtendnywbatcouihtbezwantattbebeartomtbepanhekdcresponseyroupssureiztbezcantbaveleenresponsdliemortbeoutlreaganhwbatweretbezhodnyatcopdhesperateizwanttotagetbdstobarrztotaigtobdkaloutdtluttbemdnaiparayrapbstoppehkednkztracgswbzoneartbhoestrdndtztbdngdkdybtfodntbekwbatbavedsadhorhonetbatwouihkagetbektbdngdcouihleatradtoranhwdiitbatkagebarrzhdstrustketoodknotsuredcantagetbatrdsgdkdybtbavetomdndsbtbdskdssdonaione'"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 25,
    "id": "bbe56403-8038-4659-9f3d-7056ef60e665",
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "'xefpvoduheauuachednettagehiddeoiouhevodesmziogcpdepfaoinageteouiokvolnaimupqepqmeauuhevtenbattziunighuhawetmiqqedqatuvtbvumvclimzhasszaodihadamseadzfigvsedpvuuhauuheznighuuszupcpnnvoicaueuhitxazuhecpotqisaczhadawpideddeuecuipofpspwesaceouvsztpuhezxesevomilemzupnaleuhenitualepfteodiognettageteyqmiciumzaddsetteduppoeaopuhesiuitamxaztbetuopuupnalemioltbeuxeeonenbestpfaoeuxpslaodaxemmhiddeonettageiokvolnaimawpidtuhausitletqeciammzifiuitxidemzditusibvuedbzpoepfuhebpuoeuxpsltmileuhitpoeixatuppfpcvttedpouhedecszquaufistuaodxatouseadiogxhauiutaidvouimifpvodhesoanetuasiogbaclauneauuheeodqeshaqtxethpvmdhaweamseadzseamiteduhauusioiuzcpvmdbeiowpmwedbvuiuoewespccvssedupneuhauhesoanexataozuhiogpuhesuhaoacpiocideoceuhefacuthetchasmietoiecethpvmdhawemiuvquhemighutpouhedathbpasduhpvghaodianxpssieduhauhasszdidousaiteiuqeshaqtheitamseadzthadpxioghesaoddidoumileuptaztppvupfmpzamuzbvuhedidouuemmneuhauaodtpnehpxiuhiolhexpvmdiuhioliutnpsemilemzuhauthetbezpodtvtqicipoiohitniodthehatqmazedaoinqpsuaouspmeiohitoeuxpslfpsfpvsueeozeastaoduhefacuuhauthenighubeadpvbmeageouximmbeaseambmpxuhauxatbadbvuiuxatouuhexpstupfiuuhedeuaimusioiuzgiwetpouhecpotqisacztseceouacuiwiuietitusvmzfsighueoiogxhaucpvmduhezxaouauuheheasupfuheqaodenicsetqpotegspvqttvsemzuhezcaouhawebeeosetqpotibmefpsuhepvubsealaodxhauxeseuhezdpiogaucpqidetqesauemzxaouupualeuhituphasszupuamluphinabpvuiubvuuhefioamqasagsaqhtupqqedneionzusacltxhzpoeasuhdpetusioiuzuhiolinighukpiouhenxhauhaweitaidpsdpoeuhauxpvmdnaleuhenuhiolicpvmdbeausaiupsaodximmuhaunalehasszditusvtuneuppinoputvseicaoualeuhausitlinighuhaweupfioithuhitnittipoampoe'"
+       "'wefoundtheattachedmessagehiddenintheunderlyingcodeofanimagesentinjunkmailtopeopleattheusembassyitmighthaveslippedpastusbutluckilyharryandihadalreadyfiguredoutthattheymighttrytocommunicatethiswaytheconspiracyhadavoideddetectionforoveracenturysotheywereunlikelytomakethemistakeofsendingmessagesexplicitlyaddressedtooneanotheritisalwaysbestnottomakelinksbetweenmembersofanetworkandawellhiddenmessageinjunkmailavoidsthatriskespeciallyifitiswidelydistributedbyoneofthebotnetworkslikethisoneiwastoofocussedonthedecryptatfirstandwasntreadingwhatitsaiduntilifoundhernamestaringbackatmeattheendperhapsweshouldhavealreadyrealisedthattrinitycouldbeinvolvedbutitneveroccurredtomethathernamewasanythingotherthanacoincidencethefactshescharliesnieceshouldhavelitupthelightsonthedashboardthoughandiamworriedthatharrydidntraiseitperhapsheisalreadyshadowingheranddidntliketosaysooutofloyaltybuthedidnttellmethatandsomehowithinkhewouldithinkitsmorelikelythatshesbeyondsuspicioninhismindshehasplayedanimportantroleinhisnetworkforfourteenyearsandthefactthatshemightbeadoubleagentwillbearealblowthatwasbadbutitwasnttheworstofitthedetailtrinitygivesontheconspiracysrecentactivitiesistrulyfrighteningwhatcouldtheywantattheheartofthepandemicresponsegroupssurelytheycanthavebeenresponsiblefortheoutbreakandwhatweretheydoingatcopidesperatelywanttotakethistoharrytotalktohimaboutitbutthefinalparagraphstoppedmeinmytrackswhyonearthdoestrinitythinkimightjointhemwhathaveisaidordonethatwouldmakethemthinkicouldbeatraitorandwillthatmakeharrydistrustmetooimnotsureicantakethatriskimighthavetofinishthismissionalone'"
       ]
      },
-     "execution_count": 15,
+     "execution_count": 25,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "xca = polybius_decipher(sca, keyword='a', column_order=col_a, row_order=row_a,\n",
-    "                  column_first=col_first_a, wrap_alphabet=wrap_a)\n",
-    "xca"
+    "pa = polybius_decipher(sca, keyword='a', column_order=col_a, row_order=row_a,\n",
+    "                  column_first=col_first_a, wrap_alphabet=wrap_a,\n",
+    "                  letters_to_merge={'z': 'y'})\n",
+    "pa"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 26,
    "id": "81c5bc01-b60b-4d26-9f19-231854f4f6de",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'abcdefghiklmnopqrstuvwxyzj'"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "word_a, _ = monoalphabetic_sa_break(xca)\n",
-    "word_a"
+    "word_a, _ = monoalphabetic_sa_break(xca)\n",
+    "word_a"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 27,
    "id": "7aa6dff2-f12c-4212-83df-3a9bb7b76334",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'wefoundtheattachedmessagehiddenintheunderlyingcodeofanimagesentinjunkmailtopeopleattheusembassyitmighthaveslippedpastusbutluckilyharryandihadalreadyfiguredoutthattheymighttrytocommunicatethiswaytheconspiracyhadavoideddetectionforoveracenturysotheywereunlikelytomakethemistakeofsendingmessagesexplicitlyaddressedtooneanotheritisalwaysbestnottomakelinksbetweenmembersofanetworkandawellhiddenmessageinjunkmailavoidsthatriskespeciallyifitiswidelydistributedbyoneofthebotnetworkslikethisoneiwastoofocussedonthedecryptatfirstandwasntreadingwhatitsaiduntilifoundhernamestaringbackatmeattheendperhapsweshouldhavealreadyrealisedthattrinitycouldbeinvolvedbutitneveroccurredtomethathernamewasanythingotherthanacoincidencethefactshescharliesnieceshouldhavelitupthelightsonthedashboardthoughandiamworriedthatharrydidntraiseitperhapsheisalreadyshadowingheranddidntliketosaysooutofloyaltybuthedidnttellmethatandsomehowithinkhewouldithinkitsmorelikelythatshesbeyondsuspicioninhismindshehasplayedanimportantroleinhisnetworkforfourteenyearsandthefactthatshemightbeadoubleagentwillbearealblowthatwasbadbutitwasnttheworstofitthedetailtrinitygivesontheconspiracysrecentactivitiesistrulyfrighteningwhatcouldtheywantattheheartofthepandemicresponsegroupssurelytheycanthavebeenresponsiblefortheoutbreakandwhatweretheydoingatcopidesperatelywanttotakethistoharrytotalktohimaboutitbutthefinalparagraphstoppedmeinmytrackswhyonearthdoestrinitythinkimightjointhemwhathaveisaidordonethatwouldmakethemthinkicouldbeatraitorandwillthatmakeharrydistrustmetooimnotsureicantakethatriskimighthavetofinishthismissionalone'"
-      ]
-     },
-     "execution_count": 24,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "pa = keyword_decipher(xca, word_a)\n",
-    "pa"
+    "pa = keyword_decipher(xca, word_a)\n",
+    "pa"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 28,
    "id": "c7f2e770-8062-4d18-b90a-cb2e410ef88c",
    "metadata": {},
    "outputs": [
index 56140fa94d5f9752ffb7665a072050e5e62301ae..ee251e242489ed7e60727aa6e70178d7f516e01f 100644 (file)
@@ -73,19 +73,20 @@ polybius_decipher(sca, keyword=word_a, column_order=col_a, row_order=row_a,
 ```
 
 ```python
-xca = polybius_decipher(sca, keyword='a', column_order=col_a, row_order=row_a,
-                  column_first=col_first_a, wrap_alphabet=wrap_a)
-xca
+pa = polybius_decipher(sca, keyword='a', column_order=col_a, row_order=row_a,
+                  column_first=col_first_a, wrap_alphabet=wrap_a,
+                  letters_to_merge={'z': 'y'})
+pa
 ```
 
 ```python
-word_a, _ = monoalphabetic_sa_break(xca)
-word_a
+word_a, _ = monoalphabetic_sa_break(xca)
+word_a
 ```
 
 ```python
-pa = keyword_decipher(xca, word_a)
-pa
+pa = keyword_decipher(xca, word_a)
+pa
 ```
 
 ```python
diff --git a/2021/2021-challenge8.ipynb b/2021/2021-challenge8.ipynb
new file mode 100644 (file)
index 0000000..9202b46
--- /dev/null
@@ -0,0 +1,829 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "5c19999b",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "from szyfrow.caesar import *\n",
+    "from szyfrow.affine import *\n",
+    "from szyfrow.keyword_cipher import *\n",
+    "from szyfrow.column_transposition import *\n",
+    "from szyfrow.vigenere import *\n",
+    "from szyfrow.polybius import *\n",
+    "from szyfrow.railfence import *\n",
+    "from szyfrow.support.text_prettify import *\n",
+    "\n",
+    "import numpy as np\n",
+    "import pandas as pd\n",
+    "import matplotlib.pyplot as plt\n",
+    "\n",
+    "import collections\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "d9dd1b5e",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "challenge_number = 8\n",
+    "plaintext_a_filename = f'plaintext.{challenge_number}a.txt'\n",
+    "plaintext_b_filename = f'plaintext.{challenge_number}b.txt'\n",
+    "ciphertext_a_filename = f'ciphertext.{challenge_number}a.txt'\n",
+    "ciphertext_b_filename = f'ciphertext.{challenge_number}b.txt'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "0f1f792a",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "ncb = open(ciphertext_b_filename).read()\n",
+    "\n",
+    "numtrans = ''.maketrans('12345', 'abcde')\n",
+    "cb = ncb.translate(numtrans)\n",
+    "\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "scb = sanitise(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "b8d5f9ec-27f1-498b-8e64-c5eb2424e581",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'d': 45,\n",
+       "         'e': 105,\n",
+       "         'c': 90,\n",
+       "         'r': 120,\n",
+       "         'o': 43,\n",
+       "         'a': 76,\n",
+       "         'k': 113,\n",
+       "         'n': 44,\n",
+       "         'y': 110,\n",
+       "         'z': 91,\n",
+       "         'j': 60,\n",
+       "         'l': 111,\n",
+       "         'p': 91,\n",
+       "         'w': 45,\n",
+       "         'f': 110,\n",
+       "         't': 93,\n",
+       "         'v': 118,\n",
+       "         'i': 87,\n",
+       "         'u': 61,\n",
+       "         'm': 58,\n",
+       "         'g': 43,\n",
+       "         's': 51,\n",
+       "         'x': 16,\n",
+       "         'b': 31,\n",
+       "         'h': 48,\n",
+       "         'q': 17})"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sca_counts = collections.Counter(sca)\n",
+    "sca_counts"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "b5cabba1-ac75-46ea-ac05-8699cc88d986",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<AxesSubplot:>"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "pd.Series(sca_counts).sort_index().plot.bar()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "583312cf-a973-4671-9ba8-85fe10cb9e00",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('harry', -6318.403758350804)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score_a = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "key_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "b371ff9c-dbe0-43d9-95a4-1b6766090a6e",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'wellthatwasasurpriseifoundtheattachedletteronmydoormatinacopyofthelocalmagazineitwascleverreallythereisnowaytotrackbacktohowitgotthereandnopointinwastingtimeorresourcestryingtofindoutinanycaseitwasclearthattrinitysentitandequallyclearwhatshewantedeventheciphertheyhaveusedisamessagetomeitisdoubleencryptedwiththesecondstageusingthesamepolybiusgridiusedformylastdiaryentrytheyaretellingmethatihavenowheretohideonceistrippedthatoffiwasleftwithastandardbuttrickyciphertobreakfortunatelyilearnedthedarkartsoffrequencyanalysisandcribbingfromharrysoitdidnttakelongtocrackitthesecondsurpriseisthatidontknowwhattodonormallyanyunsolicitedapproachlikethiswouldbeinstantlyreportedtothelamplighterssotheycouldinvestigatebutastrinitypointsoutihadalreadyconcealedthelastinterceptfromharryworriedthatitmightdamagehistrustinmeitwillnotlookgoodifhefindsthatoutfromthembutifitellhimtheniwillalsohavetotellhimaboutthisdirectappealtojointhemidontthinkthatwillmakethingsanybetterbetweenusthereissomethingelsetoothefoundersoftheconspiracyarepersonalheroesofmineandicantbeartothinkthattheymighthavebeenworkingforthedarksideifitistruetheniwouldratherfindoutformyselfthanleaveittoothersinbossisupposeicouldtellallandoffertoinfiltratetheagencybutthehistoryofdoubleagentsisnotahappyoneitishardtoreallytrustsomeonewhohasworkedfortheoppositioneveniftheydoitundercovertoomanyhavebeencorruptedbythecompromisesrequiredandiamnotsureiamcutoutforthatsortofworkidontthinkharrywouldinsistbutiamcertainsomebodyinbosswouldthetalkofthepandemicandcopwillbearedflagandsomeonesomewherewillbedesperatetobreakintotheconspiracydesperateenoughtomakemeanoffericantrefuseiwillhavetotakethisfurtherbutbeforeiagreetomeettrinityineedtoknowmorethenameofthesouterpointlighthouseringsabellbuticantrememberwhereicameacrossitiwillhavetogetthetraineestofigureoutwhyitmightbeimportantmeanwhileihaveanothermoreurgenttriptomaketomassourie'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sca, key_a)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "c8506a7a-4444-4929-93e4-70d1e4d6f0cc",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "well that was a surprise i found the attached letter on my doormat in a copy of the local magazine\n",
+      "it was clever really there is no way to trackback to how it got there and no point in wasting time\n",
+      "or resources trying to find out in any case it was clear that trinity sent it and equally clear what\n",
+      "she wanted even the cipher they have used is a message to me it is double encrypted with the second\n",
+      "stage using the same polybius grid i used for my last diary entry they are telling me that i have\n",
+      "nowhere to hide once i stripped that off i was left with a standard but tricky cipher to break\n",
+      "fortunately i learned the dark arts of frequency analysis and cribbing from harry so it didnt take\n",
+      "long to crack it the second surprise is that i dont know what to do normally any unsolicited\n",
+      "approach like this would be instantly reported to the lamplighters so they could investigate but as\n",
+      "trinity points out i had already concealed the last intercept from harry worried that it might\n",
+      "damage his trust in me it will not look good if he finds that out from them but if i tell him then i\n",
+      "will also have to tell him about this direct appeal to join them i dont think that will make things\n",
+      "any better between us there is something else too the founders of the conspiracy are personal heroes\n",
+      "of mine and icant bear to think that they might have been working for the darkside if it is true\n",
+      "then i would rather find out for myself than leave it to others in boss i suppose i could tell all\n",
+      "and offer to infiltrate the agency but the history of double agents is not a happy one it is hard to\n",
+      "really trust someone who has worked for the opposition even if they do it undercover too many have\n",
+      "been corrupted by the compromises required and i am not sure i am cutout for that sort of work i\n",
+      "dont think harry would insist but i am certain somebody in boss would the talk of the pandemic and\n",
+      "cop will be a red flag and someone somewhere will be desperate to break into the conspiracy\n",
+      "desperate enough to make mean offer icant refuse i will have to take this further but before i agree\n",
+      "to meet trinity i need to know more the name of the souter point lighthouse rings a bell but icant\n",
+      "remember where i came across it i will have to get the trainees to figure out why it might be\n",
+      "important meanwhile i have another more urgent trip to make to mass our ie\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "46512a70-68d4-4ea9-8f66-b39966232fa6",
+   "metadata": {
+    "Collapsed": "false",
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2333"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "4262216b-efed-491e-ade1-d7e8dffe4454",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'wemounhtbeattacbehkessayebdhhendntbeunherizdnycoheomandkayesentdnfungkaditopeopieattbeuseklasszdtkdybtbavesidppehpastuslutiucgdizbarrzanhdbahaireahzmdyurehouttbattbezkdybttrztocokkundcatetbdswaztbeconspdraczbahavodhehhetectdonmoroveracenturzsotbezwereunidgeiztokagetbekdstageomsenhdnykessayesexpidcdtizahhressehtooneanotberdtdsaiwazslestnottokageidngsletweenkeklersomanetworganhaweiibdhhenkessayednfungkadiavodhstbatrdsgespecdaiizdmdtdswdheizhdstrdlutehlzoneomtbelotnetworgsidgetbdsonedwastoomocussehontbehecrzptatmdrstanhwasntreahdnywbatdtsadhuntdidmounhbernakestardnylacgatkeattbeenhperbapswesbouihbaveaireahzreaidsehtbattrdndtzcouihlednvoivehlutdtneveroccurrehtoketbatbernakewasanztbdnyotbertbanacodncdhencetbemactsbescbaridesndecesbouihbaveidtuptbeidybtsontbehasbloarhtbouybanhdakworrdehtbatbarrzhdhntradsedtperbapsbedsaireahzsbahowdnyberanhhdhntidgetosazsooutomiozaitzlutbehdhntteiiketbatanhsokebowdtbdngbewouihdtbdngdtskoreidgeiztbatsbeslezonhsuspdcdondnbdskdnhsbebaspiazehandkportantroiednbdsnetworgmormourteenzearsanhtbemacttbatsbekdybtleahoulieayentwdiileareailiowtbatwaslahlutdtwasnttbeworstomdttbehetaditrdndtzydvesontbeconspdraczsrecentactdvdtdesdstruizmrdybtendnywbatcouihtbezwantattbebeartomtbepanhekdcresponseyroupssureiztbezcantbaveleenresponsdliemortbeoutlreaganhwbatweretbezhodnyatcopdhesperateizwanttotagetbdstobarrztotaigtobdkaloutdtluttbemdnaiparayrapbstoppehkednkztracgswbzoneartbhoestrdndtztbdngdkdybtfodntbekwbatbavedsadhorhonetbatwouihkagetbektbdngdcouihleatradtoranhwdiitbatkagebarrzhdstrustketoodknotsuredcantagetbatrdsgdkdybtbavetomdndsbtbdskdssdonaione'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "word_a, wrap_a, col_a, row_a, col_first_a = key_a\n",
+    "polybius_decipher(sca, keyword=word_a, column_order=col_a, row_order=row_a,\n",
+    "                  column_first=col_first_a, wrap_alphabet=wrap_a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "bbe56403-8038-4659-9f3d-7056ef60e665",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'pafdmtiswsencmysllreooojytttyisirmenpsuuoyaawttriweotyotnunpiscaoemuciepiagopawggrptioyhbrliuoekskltttnhofendeoeoawowednemeeegoopuengermnbiwnedoeoarcnfhdmsoiapwoaefseryohyrehagtdinyooerofnirdconotitaoisleottswonailntuhisohwhwdirifinnayrneadrschnosalfpycrshooneyiuodamgrheeikaindeieteayhabuudiordruiheyydeeerncarobhmueodykotirutwrysaitcubkecviihonnuulofaufsemciodeelsacntaebrtyewdsooahcilirooybllupaaunpdndmgtfnnoeftnfyeeuoteoehatagaiuowuooemsrenieosouvrntcelupsuteupdwbureiolacrituhrisioittnthahylrtstdhleiysowoeelbwhegatodisyaddaattbrahdiowwrtrehthomrelionessipetltrtaiahcydglbrsnorkaftontrdorlaaoostaahtttuionidtebrrboehwnicordaeheytepltnnoybltohlniirteleoshtnefneloesoeocsouulkvhsydrtntkannnecroohbreurrixhetjoeoioocaboroefometuoebtyiotensotelueyfenieswtruoriwusetwrucrwktaeattnertarcruescsenrmaasuaootedsdbuoeahafgonvntahoeuedreareuoeaudttwhoeaetbhvonetrgtreddtaogrteouvstiodletiofaaahleoiaaeecaemoybhsoyytahirhacttocidoerliyttehtnmnmcsuehdcuhdaoorhhceunktetthyhuerohioslegneiieopeaoriaeyftldiegaihgtiunhenlogsanhnveeptnyotipayldhmhcfmoepaptsuysuynyelirasinagollghgsyetussbmnkenpooroodrtddgtruuetetcuioomfrarihyoslsahwispkennepivtsluiltochaanuirpiclecinvoeitdhatnuceilrnpnuoeiisisinloiceerweeiultitatwmsuowbdirenycnrlthuuaaeybylaliiweeihoyeteuthrsrtiurecoultoistvepgetunhegowricleiwhiaartahnhuosleairtnupeneloreoelouigeaooyneronuooybrttongeraeutcbolnohhytonthorsgrtrltttnnoterdpnsawenawfioytjoatsdfnureeydeoceevlngmrlxnlofaptddbtsttsuthnghcaaernefwbfamcaatoeoylstneotrgrwgttuioeiavhitltorutcgyulbaapvutdodtseypmhoeinsrnestgasoithiisnehitikrbegktnetehduitdteiaelohpirotitenashottptcnktsutiarwotduftetwuvtidodautanhkftedlultriaooemstdeuaebtahoyoisbhcirhtoyiweawduedthtuiscrealrglrswelneuteepnswiietgavahhnynakoaueshengityeboecrtitlesimreaiavrtnytaieoaadetasuynbantnnrheykfiareochlifwtsdeeytttorklmitviageffohoothntrodeeaaiheftivoyut'"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "xcb = polybius_decipher(scb, keyword='a', column_order='abcde', row_order='abcde',\n",
+    "                  column_first=False, wrap_alphabet=KeywordWrapAlphabet.from_a,\n",
+    "                  letters_to_merge={'z': 'y'})\n",
+    "xcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "id": "77a5c146-fa17-41db-9908-7bf2645fe3a1",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'pafdmtiswsencmysllreooojytttyisirmenpsuuoyaawttriweotyotnunpiscaoemuciepiagopawggrptioyhbrliuoekskltttnhofendeoeoawowednemeeegoopuengermnbiwnedoeoarcnfhdmsoiapwoaefseryohyrehagtdinyooerofnirdconotitaoisleottswonailntuhisohwhwdirifinnayrneadrschnosalfpycrshooneyiuodamgrheeikaindeieteayhabuudiordruiheyydeeerncarobhmueodykotirutwrysaitcubkecviihonnuulofaufsemciodeelsacntaebrtyewdsooahcilirooybllupaaunpdndmgtfnnoeftnfyeeuoteoehatagaiuowuooemsrenieosouvrntcelupsuteupdwbureiolacrituhrisioittnthahylrtstdhleiysowoeelbwhegatodisyaddaattbrahdiowwrtrehthomrelionessipetltrtaiahcydglbrsnorkaftontrdorlaaoostaahtttuionidtebrrboehwnicordaeheytepltnnoybltohlniirteleoshtnefneloesoeocsouulkvhsydrtntkannnecroohbreurrixhetjoeoioocaboroefometuoebtyiotensotelueyfenieswtruoriwusetwrucrwktaeattnertarcruescsenrmaasuaootedsdbuoeahafgonvntahoeuedreareuoeaudttwhoeaetbhvonetrgtreddtaogrteouvstiodletiofaaahleoiaaeecaemoybhsoyytahirhacttocidoerliyttehtnmnmcsuehdcuhdaoorhhceunktetthyhuerohioslegneiieopeaoriaeyftldiegaihgtiunhenlogsanhnveeptnyotipayldhmhcfmoepaptsuysuynyelirasinagollghgsyetussbmnkenpooroodrtddgtruuetetcuioomfrarihyoslsahwispkennepivtsluiltochaanuirpiclecinvoeitdhatnuceilrnpnuoeiisisinloiceerweeiultitatwmsuowbdirenycnrlthuuaaeybylaliiweeihoyeteuthrsrtiurecoultoistvepgetunhegowricleiwhiaartahnhuosleairtnupeneloreoelouigeaooyneronuooybrttongeraeutcbolnohhytonthorsgrtrltttnnoterdpnsawenawfioytjoatsdfnureeydeoceevlngmrlxnlofaptddbtsttsuthnghcaaernefwbfamcaatoeoylstneotrgrwgttuioeiavhitltorutcgyulbaapvutdodtseypmhoeinsrnestgasoithiisnehitikrbegktnetehduitdteiaelohpirotitenashottptcnktsutiarwotduftetwuvtidodautanhkftedlultriaooemstdeuaebtahoyoisbhcirhtoyiweawduedthtuiscrealrglrswelneuteepnswiietgavahhnynakoaueshengityeboecrtitlesimreaiavrtnytaieoaadetasuynbantnnrheykfiareochlifwtsdeeytttorklmitviageffohoothntrodeeaaiheftivoyut'"
+      ]
+     },
+     "execution_count": 62,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sncb = cat(l for l in ncb if l in '12345')\n",
+    "xcb = polybius_decipher(sncb, keyword='a', column_order='12345', row_order='12345',\n",
+    "                  column_first=False, wrap_alphabet=KeywordWrapAlphabet.from_a,\n",
+    "                  letters_to_merge={'z': 'y'})\n",
+    "xcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "id": "24d8ad2e-b237-479b-9a62-af9bc8d100d5",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'p': 34,\n",
+       "         'a': 131,\n",
+       "         'f': 33,\n",
+       "         'd': 66,\n",
+       "         'm': 29,\n",
+       "         't': 186,\n",
+       "         'i': 134,\n",
+       "         's': 84,\n",
+       "         'w': 43,\n",
+       "         'e': 208,\n",
+       "         'n': 115,\n",
+       "         'c': 49,\n",
+       "         'y': 63,\n",
+       "         'l': 70,\n",
+       "         'r': 114,\n",
+       "         'o': 179,\n",
+       "         'j': 3,\n",
+       "         'u': 91,\n",
+       "         'g': 38,\n",
+       "         'h': 92,\n",
+       "         'b': 33,\n",
+       "         'k': 19,\n",
+       "         'v': 18,\n",
+       "         'x': 2})"
+      ]
+     },
+     "execution_count": 63,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb_counts = collections.Counter(xcb)\n",
+    "scb_counts"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "id": "d66dd0d0-badb-44f3-a8a6-f7edd17d1532",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<AxesSubplot:>"
+      ]
+     },
+     "execution_count": 64,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "pd.Series(scb_counts).sort_index().plot.bar()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "id": "60b68dbb-7e93-4ba6-aca3-2aebe2902a70",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<AxesSubplot:>"
+      ]
+     },
+     "execution_count": 65,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "pd.Series(english_counts).sort_index().plot.bar()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "id": "e7a1c634-7050-4620-a970-713fde32af40",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "24"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(set(xcb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "id": "81c5bc01-b60b-4d26-9f19-231854f4f6de",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((4, 2, 1, 6, 3, 5, 0), False, True)"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, _ = column_transposition_break(xcb, fitness=Ptrigrams)\n",
+    "word_b, fill_b, empty_b = key_b\n",
+    "word_b, fill_b, empty_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "id": "7aa6dff2-f12c-4212-83df-3a9bb7b76334",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'isuspectyoualreadyfoundandreadmymessagetocharliesothisletterwontbeasurpriseimtakingachanceandiamaskingyoutodosoaswellyouwillnotregretittherearegoodreasonswhyyoudothejobthatyoudobutyoumustbefrustratedbythelimitationsofworkingundergovernmentsupervisionandihopetopersuadeyouthatyoucoulddobetteryouaretalentedandhardworkingthefactthatharryrecruitedyouwouldbeenoughtotellmethatbutyourrecordisoutstandingtooyourworkonthekompromatfilesfirstattractedourattentionbutwhenharrymovedyoutobosscentralirealisedthatapproachingyouwastoobigarisksowesteppedbackandhavewatchingwaitingfortherightopportunitytoinviteyoutojoinusyouwillhavedoubtsatfirstwealldidbutifourfounderscouldbeheretomakethecaseithinkyouwouldfinditeasiertoacceptcarolineherscheladalovelaceflorencenightingaleandmaryeverestboolewereexceptionallytalentedwomenwhofoundawaytostepbeyondtheboundsplacedonthembysocietywhilestillretainingtheirpositionourgroupthatyouhavebeencallingthelighthouseconspiracyhasmaintainedanunbrokenlineofpowerandinfluencewieldedbysomeofthegreatestwomenofeachgenerationicantcountmyselfoneofthembutidocountmyselfasluckytoservewiththemandisuspectyouwouldtootherewardstobegainedfromthisworkaregreaterthananythingyoucanachieveinyourcurrentroleiknowthatyouhavethoughtaboutitireadtheemailyousentharryyouareboredinyourexiletothearchaeologistsifyoujoinusyouwillneverbeboredagainicannothopetoconvinceyouinaletterbutidohopetopersuadeyoutotakethisofferseriouslyiampreparedtomeetwithyoubutofcoursetherewillbeconditionsifyouarewillingtoatleastconsideritthenisuggestthatyouvisitthesouterpointlighthousewhereithinkyouwillfindsomethinginterestingihavetofinishwithawarningthinkverycarefullybeforereportingthisweknowthatyoudidnotsharethelastinterceptwithharryandyoushouldconsiderwhathewouldmakeofthatespeciallyifhebecameawareofthisletterhopingtohaveanopportunitytopersuadeyoutrinity'"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(xcb, word_b, \n",
+    "        fillcolumnwise=fill_b, emptycolumnwise=empty_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "id": "c7f2e770-8062-4d18-b90a-cb2e410ef88c",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "i suspect you already found and read my message to charlie so this letter wont be a surprise im\n",
+      "taking a chance and i a masking you to do so as well you will not regret it there are good reasons\n",
+      "why you do the job that you do but you must be frustrated by the limitations of working under\n",
+      "government supervision and i hope to persuade you that you could do better you are talented and\n",
+      "hardworking the fact that harry recruited you would be enough to tell me that but your record is\n",
+      "outstanding too your work on the kom prom at files first attracted our attention but when harry\n",
+      "moved you to boss central i realised that approaching you was too big a risk so we stepped back and\n",
+      "have watching waiting for the right opportunity to invite you to join us you will have doubts at\n",
+      "first we all did but if our founders could be here to make the case i think you would find it easier\n",
+      "to accept caroline herschel ada lovelace florence nightingale and mary everest boole were\n",
+      "exceptionally talented women who found away to step beyond the bounds placed on them by society\n",
+      "while still retaining their position our group that you have been calling the lighthouse conspiracy\n",
+      "has maintained an unbroken line of power and influence wielded by some of the greatest women of each\n",
+      "generation icant count myself one of them but i do count myself as lucky to serve with them and i\n",
+      "suspect you would too the rewards to be gained from this work are greater than anything you can\n",
+      "achieve in your current role i know that you have thought about it i read the email you sent harry\n",
+      "you are bored in your exile to the archaeologists if you join us you will never be bored again i can\n",
+      "not hope to convince you in a letter but i do hope to persuade you to take this offer seriously i am\n",
+      "prepared to meet with you but of course there will be conditions if you are willing to atleast\n",
+      "consider it then i suggest that you visit the souter point lighthouse where i think you will find\n",
+      "something interesting i have to finish with a warning think very carefully before reporting this we\n",
+      "know that you did not share the last intercept with harry and you should consider what he would make\n",
+      "of that especially if he became aware of this letter hoping to have an opportunity to persuade you\n",
+      "trinity\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(pb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "id": "6cecddd9",
+   "metadata": {
+    "Collapsed": "false",
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2333"
+      ]
+     },
+     "execution_count": 59,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "07c92adb-74e2-476e-adff-887c0145617d",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'10101 11000'"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cb[:11]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "832dc153-c9e3-4134-9425-8014847c3870",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "21"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "int('10101', 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "d7002750-66fd-4435-8ee8-023ae8376f33",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "9865"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb = cat(c for c in cb if c in '01')\n",
+    "len(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "id": "f3c2587e-7b76-49fb-ba60-ed3efc148c85",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(0, 25)"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ncb = [int(g, 2) for g in cb.split()]\n",
+    "min(ncb), max(ncb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "bf189676-3c25-420d-9330-b77cc57c7a82",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'vyietbcbuwabmfbeslwnqafcylayovkbuxrhcwalhlpvknvmpbjszmxrbeonvwwhlznzkgortuilzxvvawmgvvlogumljprqzfmvvvvzqnjxvkbmgyiezrqmvizqlyvkqimewbedramgzrbvvzmniweotlbjigqhlteljmayovbblhcovzlbaggxerktlmfxhbmfxdwsnmfxjkrvmsgwwebnltkmygbkpfzxqgepzbudxprtwaamptzvrlkclfcekxqwvacqmctctbckntelrubaiimcikymzwaabraraomxlarzqehpdfdrzmfxcifbxgzybrmgkhebuatqiciavxbpvcfmwravkeqlglkwruucwdwemhnxiigqoclrbgpxfxrzgwyehmmevfcgklrkbqbfvzidggxcalxpmympwockfnfizctelgpxmmymevxuvfuzqmrxvajmgmpyiimtlxkebzdmyjkvmgrbjbfigbxeovvxckjqaeagmvpnteubkpgpxbbimpbxykfnfmgghikvdbjlvziigrlrvqxhjbkqpqtllkprgtjlfprticwlagwblyztgztrxtwcobtbeohawgkvkgivaxjagwtlndjrzhdhkprzzmovzauxlmjbuimftuzrutggvlomrmguwhzkcttpjpbjxnmjmkcgfbnjecmfnhtewwvtvdxphewhzijteaswkrarbrdxlmkprkhlgvkgqhllnmziwcpzbuahkxfngpxuhitqaeykxmfbvmfgiaqxqtelfutjevagamymvajqejllzrtrntpwsnblmymzmwgndbrzfmgkprlhugjqqmbftmmabaywkprktnttqggblxvlgwpmkbwabacufafqgtxjbvotrbfvvvmmhlzbzzygzanbbmgkpnbbquvqaoksgwzbumfxrzpptchcwtgwgozavwgfximnbzaahquiwfhgmqbaymrafqzlfvvguxygkbuimravknaxutjzrotpwvlnaempgzvwkgmpjhbaykignalgzemqpbquvagizcgkrblbcmfzhvbrteltiocavzntfmlkcatbkbkmqzxqhlzpmlqavpnamctdanteyviwfamfxlsgztuezvtbaphloubacirxrzluxcmsbucazvqimravtvoarafcfmtlwkzlqgemfebzdmnkeuimravgzmtlbrufwtlzignbfwlvtsnhpmyigjnrbyiimickjwaiejrtprkdcwrvqiejmymzicmkzbruldkfugpxdhlvqimgheiekagoverzxqazxcmwmnkbbutqlfceqxygupndxzxvvfmvskvlnbmfxgiesbyljqtvxbtkmnummfrsranpxkpnbmfxbmllhandmabluximczhnxitlmgakpxgmwggtifmcmwzmfbxyfwqallravuocmebmmabacmrtrvmqavqfehpdzvtebrazvbemfbesjmfgzybamxbmfbnsxdnibumkqmvxfigbbgtnvmmozavbmfxyynalmheifqvygxmgipyrnprbackfzawmhhuqrigbavzgmtkpfzxwnrpyigexykvlbqgemymomlrprggwfydvahzxrarbuikpruwragmmwqalhsmdqtpmzxkwpwgtbekrpxpgfbgwmcecpvubftmmomxlvrzegblzfcgahkxsipszphlvqkacvbanvwgtdebvwckzvtqyuxjpbcebclagbkwmfzrkksbkprzwgkvkgtrgyjpretqpfzxqgepzbuclravvvulskvaumpmnclfmxravvrmwdhiarkkcvpbumwgkvkgiinkfippbqkzaxgusmkprwketeqfimghepnagcovzfpbcwrengyphdbuimzxwwemhprfcnvwgpfcylgruvebzdggxnbzbrbkpvvdgmzanzbqdnwebartbqaormnitbdblzeqrkxrkzvvbr'"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tcb = cat(unpos(n) for n in ncb)\n",
+    "tcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "id": "59f072b0-f8ca-4f08-922d-cfb5dfc68fe4",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'beuxmwnprjiztavlsfgkqdyhco'"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "word_b, score_b = monoalphabetic_sa_break(tcb)\n",
+    "word_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "16210c33-3bcb-43c8-9189-d82eea7cf53b",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "trinity \n",
+      "\n",
+      "charlieidontthinkyoushouldhavecometolondonwecantriskmeetingandyourarrivalhasbeennoticedbybossheighteningsuspicionharrysteamisactivelyinvestigatingourorganisationandwehavetodoeverythingwecantoputthemoffthescentunfortunatelyimworkingwithveryconstrainedresourcesdespiteallourpandemicpreparationsithasbeenhardworkoverthelasteighteenmonthsasplannedweusedthecrisistoembedmoreoperativesattheheartofgovernmentdecisionmakingunderthecoverofsageandtheothernewcommitteeswenowhaveanetworkofscientistsandengineersinwhitehallwiththedirectearofseniorcivilservantsandpoliticianstheyalsohelpedustoinfiltratecopgivingusdirectaccesstoanumberofothergovernmentsthathadremainedbeyondourreachwhilewewerenotabletofullydeliveronourplansforthateventtheconnectionswemadewithsomeoftheworldslargestcompaniesandsmalleststateswillsurelypayoffinthemediumtermonthedownsideihaventhadthecapacityineedtoworkonthebossinvestigationintoourorganisationthatisbeingrunfromthearchaeologydivisionhereatgchqihadhopedthatassignmentmeantthatthecasewasregardedaslowprioritybutharryassignedhisbestagentjodietorunitandgaveheralmostunlimitedresourcesshehasteamsallacrosstheuktrawlingthroughthepapersweleftbehindatthelighthouseandtryingtoworkoutwhattheymeaniamsoangryatmyselfforthatbutihavepersonallycheckedandallthemajoritemsfromthefoundationarchivewereshippedouttomassourieandhavebeensecuredattheparkiassignedateamtomakesurethatthekeydocumentswereproperlyencryptedincasejodiesteamfindsthembutgiventhetalentsheisworkingwithinowthinkwemightneedtotakefurtherstepsandiplantovisitthehqassoonasicangetawaywhetherornotjodieandherteamworkoutwhatwearedoingthebestwaytomakesurethatharrydoesnotfindoutmightbetoconvincehernottotellhimihavebeencarryingoutsomebackgroundchecksandiamwonderingifweshouldjusttrytorecruitherdirectlyifshewasworkingwithusthenimsureshewouldseetheneedforsecrecythedirectapproachisriskybuttheorganisationhasnevershiedawayfromthatbeforeoryouandiwouldntbeworkingforitithinkitisariskworthtakingyourlovingniecetrinity\n"
+     ]
+    }
+   ],
+   "source": [
+    "word_b, score_b = vigenere_frequency_break(tcb, fitness=Ptrigrams)\n",
+    "print(word_b, '\\n')\n",
+    "pb = vigenere_decipher(tcb, word_b)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "id": "fe094361-7c85-40d9-952e-0c84abbcf903",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie i dont think you should have come to london we cant risk meeting and your arrival has been\n",
+      "noticed by boss heightening suspicion harry steam is actively investigating our organisation and we\n",
+      "have to do everything we can to put them off the scent unfortunately im working with very\n",
+      "constrained resources despite all our pandemic preparations it has been hard work over the last\n",
+      "eighteen months as planned we used the crisis to embed more operatives at the heart of government\n",
+      "decisionmaking under the cover of sage and the other new committees we now have a network of\n",
+      "scientists and engineers in whitehall with the direct ear of senior civil servants and politicians\n",
+      "they also helped us to infiltrate cop giving us direct access to a number of other governments that\n",
+      "had remained beyond our reach while we were notable to fully deliver on our plans for that event the\n",
+      "connections we made with some of the worlds largest companies and smallest states will surely payoff\n",
+      "in the medium term on the downside i havent had the capacity i need to work on the boss\n",
+      "investigation into our organisation that is being run from the archaeology division here at gchq i\n",
+      "had hoped that assignment meant that the case was regarded as low priority but harry assigned his\n",
+      "best agent jodie to run it and gave her almost unlimited resources she has teams all across the uk\n",
+      "trawling through the papers we left behind at the lighthouse and trying to workout what they mean i\n",
+      "am so angry at myself for that but i have personally checked and all the major items from the\n",
+      "foundation archive were shipped out to mass our ie and have been secured at the park i assigned a\n",
+      "team to make sure that the key documents were properly encrypted in case jodie steam finds them but\n",
+      "given the talent she is working with i now think we might need to take further steps and i plan to\n",
+      "visit the hq as soon as i can getaway whether or not jodie and her teamwork out what we are doing\n",
+      "the best way to make sure that harry does not find out might be to convince her not to tell him i\n",
+      "have been carrying out some background checks and i am wondering if we should just try to recruit\n",
+      "her directly if she was working with us then im sure she would see the need for secrecy the direct\n",
+      "approach is risky but the organisation has never shied away from that before or you and i wouldnt be\n",
+      "working for it i think it is a risk worth taking your loving niece trinity\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(pb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "id": "d12a663c",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2420"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(prettify(pb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "504ec2e2",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/2021/2021-challenge8.md b/2021/2021-challenge8.md
new file mode 100644 (file)
index 0000000..4bb2ff7
--- /dev/null
@@ -0,0 +1,185 @@
+---
+jupyter:
+  jupytext:
+    formats: ipynb,md
+    text_representation:
+      extension: .md
+      format_name: markdown
+      format_version: '1.3'
+      jupytext_version: 1.11.1
+  kernelspec:
+    display_name: Python 3 (ipykernel)
+    language: python
+    name: python3
+---
+
+```python Collapsed="false"
+from szyfrow.caesar import *
+from szyfrow.affine import *
+from szyfrow.keyword_cipher import *
+from szyfrow.column_transposition import *
+from szyfrow.vigenere import *
+from szyfrow.polybius import *
+from szyfrow.railfence import *
+from szyfrow.support.text_prettify import *
+
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+
+import collections
+%matplotlib inline
+```
+
+```python Collapsed="false"
+challenge_number = 8
+plaintext_a_filename = f'plaintext.{challenge_number}a.txt'
+plaintext_b_filename = f'plaintext.{challenge_number}b.txt'
+ciphertext_a_filename = f'ciphertext.{challenge_number}a.txt'
+ciphertext_b_filename = f'ciphertext.{challenge_number}b.txt'
+```
+
+```python Collapsed="false"
+ca = open(ciphertext_a_filename).read()
+ncb = open(ciphertext_b_filename).read()
+
+numtrans = ''.maketrans('12345', 'abcde')
+cb = ncb.translate(numtrans)
+
+sca = sanitise(ca)
+rsca = cat(reversed(sca))
+scb = sanitise(cb)
+rscb = cat(reversed(scb))
+```
+
+```python
+sca_counts = collections.Counter(sca)
+sca_counts
+```
+
+```python tags=[]
+pd.Series(sca_counts).sort_index().plot.bar()
+```
+
+```python
+key_a, score_a = vigenere_frequency_break(sca, fitness=Ptrigrams)
+key_a, score_a
+```
+
+```python
+pa = vigenere_decipher(sca, key_a)
+pa
+```
+
+```python
+print(prettify(pa))
+```
+
+```python Collapsed="false" tags=[]
+open(plaintext_a_filename, 'w').write(prettify(pa))
+```
+
+```python
+word_a, wrap_a, col_a, row_a, col_first_a = key_a
+polybius_decipher(sca, keyword=word_a, column_order=col_a, row_order=row_a,
+                  column_first=col_first_a, wrap_alphabet=wrap_a)
+```
+
+```python
+xcb = polybius_decipher(scb, keyword='a', column_order='abcde', row_order='abcde',
+                  column_first=False, wrap_alphabet=KeywordWrapAlphabet.from_a,
+                  letters_to_merge={'z': 'y'})
+xcb
+```
+
+```python
+sncb = cat(l for l in ncb if l in '12345')
+xcb = polybius_decipher(sncb, keyword='a', column_order='12345', row_order='12345',
+                  column_first=False, wrap_alphabet=KeywordWrapAlphabet.from_a,
+                  letters_to_merge={'z': 'y'})
+xcb
+```
+
+```python
+scb_counts = collections.Counter(xcb)
+scb_counts
+```
+
+```python tags=[]
+pd.Series(scb_counts).sort_index().plot.bar()
+```
+
+```python tags=[]
+pd.Series(english_counts).sort_index().plot.bar()
+```
+
+```python
+len(set(xcb))
+```
+
+```python
+key_b, _ = column_transposition_break(xcb, fitness=Ptrigrams)
+word_b, fill_b, empty_b = key_b
+word_b, fill_b, empty_b
+```
+
+```python
+pb = column_transposition_decipher(xcb, word_b, 
+        fillcolumnwise=fill_b, emptycolumnwise=empty_b)
+pb
+```
+
+```python
+print(prettify(pb))
+```
+
+```python Collapsed="false" tags=[]
+open(plaintext_a_filename, 'w').write(prettify(pa))
+```
+
+```python
+cb[:11]
+```
+
+```python
+int('10101', 2)
+```
+
+```python
+scb = cat(c for c in cb if c in '01')
+len(scb)
+```
+
+```python
+ncb = [int(g, 2) for g in cb.split()]
+min(ncb), max(ncb)
+```
+
+```python
+tcb = cat(unpos(n) for n in ncb)
+tcb
+```
+
+```python
+word_b, score_b = monoalphabetic_sa_break(tcb)
+word_b
+```
+
+```python
+word_b, score_b = vigenere_frequency_break(tcb, fitness=Ptrigrams)
+print(word_b, '\n')
+pb = vigenere_decipher(tcb, word_b)
+print(pb)
+```
+
+```python
+print(prettify(pb))
+```
+
+```python Collapsed="false"
+open(plaintext_b_filename, 'w').write(prettify(pb))
+```
+
+```python Collapsed="false"
+
+```
diff --git a/2021/ciphertext.8a.txt b/2021/ciphertext.8a.txt
new file mode 100644 (file)
index 0000000..11c470e
--- /dev/null
@@ -0,0 +1 @@
+DECCR OAKNY ZAJLP WRZJC PFFLL KTYVY ATRTF LDCVR AEIFL TYUFM YMRKG UATFN FOWKF LLFTY SMRXY GIEVG AWRJA SEMVP YERCJ FTYVP LIJEM DAPKM ARRTI IATBR VHFNG AGFKR OEIVY UDEFN VIEKG UWRJR PNXKG TEFIP LSFLP JEJKP FIEXR VFZEB VUKZL HNPTY ZEZKU HSTCC HRKYY ATIZL PTPJC UTZKY UDVHS HLCPA SERIU OAKJF LWRER LDVMC UTYVA PPYVP AHVPF HVVLQ LDZJY TEJJY NEKFK LIKZQ KOLSJ LEETP FPKVB DIKYR OEJVA VNUJR HGVLQ PNXKF LSRDC WOCPZ PUJXP PDZLQ LDWFP TYCRQ ADZRP FEEKP FTYVW HRVKC SLZEE TEKYY AIYRT LNFNF LRVKM OIUVM UCVZQ ARZGN LDKYY AOWWG DAJCC MTNZR OAJKY UDRIB IUKKP PCBPA PPYVP AOSIC HKWFP AUERR LLPZJ LAIEC KTYVB HRBRP ASFWD YEHLC UCPRL HLPJG ZAEUA YISSG UGWIM THRIP FSFZR KIUER AABVJ VNXKM JRRTI PTKYC ZETFL KSLIN YIJVG ZTYRR PDFER RNFNU OAKKM KOEFP TACCW HNPLL ZOCZA PTVUY WPIFY JHCZI LTYZQ DOLCB IEZEQ AAEKJ FRVGM YTVUR VTYVJ HMGCG NHKVP ZSFKF LYTFS SDZET LSKZE HTVSS AAJKP PNZKW WOZER ZOLKG OAURJ YERUW JOETC HLVUR OECRQ AIEKC YCVGR MRFDF HRIPU VRIZC KTYRR PTDZE OTURK HGVYG ZTILQ AIEDC PTNZJ SNFKJ VOBXM VDZWF LFZEB ZTYRR VUKWP VMKYC TBLKG MIKVJ SHZDR OEEZU PLCRJ ZOYRT LTFKC SLYZK HBFLR AHZJB PRVTR HPGVY STFAM PNKYC TIUFL ATYZL RTYRR DICCK HKVKF PNXJY UYSVR AEISC AWVVL BSKYC YEZJQ VMVKF PNXVJ ZEKFM AHVWM BNUVP ZOWKF LCFEQ WIIRA FAIVN LRJFL HLYVP VEJFD TIEVY UDZTY UTSVY YTFKF PNBKF HTKYC FMZXF AHRMC IEVEU VRBZL NFFIR OEURP RSZUC PFZKG ZTILC AHVEG DOLCB YAKYC YFZEB VUKWM YMPJC SFKYY ULVRT LIKKM VTYVP ZIESM ZSZJS WPFJC PCFLJ KTVCJ HLCRL KOWWC YTFZL MICKP HTVKF LAXVL JYSLR AHVYG ZTFIW VFUFS ILVRE LNKJG ZNFKY OAGGW VNVZR PSYRP KTFIC HLCPR YUJKQ VMVFL LWYFF HSNFP REUWM YTYVM WPFJG AIFEC CEEZD AHVPB VIKLL KEITM CEIKM VMREW OAMVZ LEETM YRLGR LDSPR OETFK WRFDG ZEJIC XUZIC KAEUG HMEFR ZUIVG HMTLR VUKWM YTYRR ZOIKM MWFII PDFER AHZEI OAIIW DOLCB PNJZQ ABLKG HMTVP AAZEQ VMVSM KYZEZ VSJNM BLUKF LTRCI VFKYC WAEUC TITRL KCFGU PLCSC HRVUD SAXRL KSFDC VNVJM TENYC YENZJ SBVUC ZPVIY AEKFZ YERBG UTFKF LCFEQ WIIRA FDVJN LRRKC LNFLE OTFDY REDVY UOWWC YITRL ARVWS ZEZNG SLYRT LTFKY REKYG ZFLIR OEISS ABVWM YEZRE YEVKM TEVKR YIEZR FIEVC KTFBL VWDFP LTYVL HMVFD AHVJM BTVIN VIEKJ PGYKF VUJVP PNXJY IECCZ BTZTY UTIVK LMSVP DHVIC PCRDC HCIFQ ZIKZU PLCYY CEKFE LTKYC ARRZL LEJKM MIXLP LOLKU OYZKK PGYKZ LIDGM YTRER TEREU OICVG OAMVY UOKYC YMFIC BRXVL ATIZN AODRI LTFDY ZSFLP PE
\ No newline at end of file
diff --git a/2021/ciphertext.8b.txt b/2021/ciphertext.8b.txt
new file mode 100644 (file)
index 0000000..b90daf3
--- /dev/null
@@ -0,0 +1 @@
+41112 11433 45244 45344 15341 33355 44323 24315 35353 52555 45454 55524 44244 33315 34414 45151 35551 11153 45454 32453 15354 55535 45345 13441 24441 31135 15335 11324 15412 41122 35411 15322 22434 14524 35552 31243 32245 13515 31443 13245 45453 42335 21153 41415 35153 51153 35531 51434 15331 51515 22353 54151 15342 21543 33341 22453 34151 43515 35114 31334 21231 43344 35241 14153 35111 52144 15435 53523 55431 52311 22451 42434 55353 51543 35213 42443 14133 53435 45244 51135 24443 21535 45454 45335 34112 43234 45512 32444 35235 32353 14244 32421 24343 41155 43341 51114 43441 32334 35441 13221 41551 34344 23353 53415 55245 13514 11332 24323 15152 43111 24341 41524 15451 51155 23111 25151 14243 54314 43512 42315 55551 41515 15433 41311 43351 22333 51153 51455 31354 52443 51455 34355 44112 44513 51123 11513 52242 42335 34345 15132 35211 15121 44153 31324 35141 51532 44111 33445 11151 24345 55155 31444 35351 12313 24322 44335 35551 23232 51411 11151 34411 43414 33224 52134 34351 52145 34215 51515 51354 51535 15231 14511 22112 45135 53513 53515 33444 31534 24153 54435 51524 33445 13153 25141 44514 51551 41145 31251 43152 43532 11134 32445 51234 32444 24352 44545 34452 31123 55324 34544 45142 33215 24554 43553 35151 53212 53231 52211 45351 42444 55111 41411 11454 51243 11231 42435 53534 34543 15234 52335 33431 53224 35341 54444 24411 54532 45434 51124 11231 35514 22321 24344 34354 33111 21453 53445 43143 54332 11113 53544 45111 12345 45455 12435 34241 44515 12434 31235 15235 33424 13354 31411 15231 55545 15413 24534 34355 51232 45352 33234 24244 34515 32153 54423 45341 52134 15323 51544 35153 51344 35515 13231 52234 45514 43453 44531 11343 43415 13433 53523 12431 55143 43245 42315 45253 51535 24353 51311 12354 33515 21353 31545 51351 51245 55243 54515 34443 54515 32511 55521 15342 41544 53454 35135 43245 35144 15455 34351 13435 33145 11151 14545 34154 34511 43134 35115 44134 41534 43331 11144 51113 53545 15144 41412 51351 51123 11212 23534 52344 51123 35155 11514 43151 14315 51351 51151 14454 55323 35151 11545 12235 23534 15454 32245 43151 41445 11352 24345 15355 15244 45243 51432 15452 43521 11111 12332 15352 41111 15151 31115 33355 51223 44355 55545 11232 44323 11134 54535 13241 43515 43322 45545 45152 34534 33343 31344 51152 31413 51231 41135 35432 32313 15513 43145 15454 52355 23511 54335 23243 54432 15223 41524 24153 54115 11354 32411 15552 14532 14241 52211 24232 24524 51342 31534 32352 24411 34233 45215 15414 53455 35452 44111 55321 42333 23132 13335 15411 14145 44515 54451 55345 51532 24431 14424 34112 23532 32222 32244 55154 55144 44123 33431 15344 13535 43353 51443 45141 42245 43515 11545 15451 35124 35353 32143 11432 42355 35443 24411 23532 44441 31153 43415 41245 24544 32512 43245 35132 31111 34512 44341 24133 21513 24345 23515 24451 42311 45345 11315 24324 33441 34513 51524 24442 44424 34323 52413 15154 35315 15245 13245 24451 14553 33445 13553 12142 44315 34551 33443 32452 35151 11111 55512 55321 13224 24531 51524 23355 51545 15514 52343 44434 52451 43151 33551 32453 52444 45521 54122 15455 13423 15223 55343 24133 21524 53232 41111 43451 12334 23513 54432 15112 44345 34514 11534 15323 54315 35153 23551 24221 51135 35553 41543 35345 13535 55124 34545 35342 21543 11155 14513 12353 23435 23235 54535 34452 33543 44224 34543 32454 54534 34354 51543 14413 44411 53153 41153 21243 55545 25351 14544 14213 45143 15155 51415 35131 51552 32342 23343 32543 43235 21114 14514 14124 54445 45445 14523 34222 31311 11154 33415 21531 22111 33131 11145 35153 55532 44453 41535 45432 24353 22454 55124 35152 41152 23244 53245 35435 14513 22555 13212 11114 15251 45143 51445 44155 54133 23351 52434 44433 41544 45221 14435 24452 32424 44341 52324 45243 14312 15223 14534 15451 52314 51244 51445 15241 11532 35234 12443 35452 44515 34114 42335 45454 14513 34314 54451 45241 14353 35451 45121 45154 55351 52452 41435 14115 14511 34233 12145 15143 25132 45432 41135 35153 34445 14155 11115 12451 12335 55352 44412 23132 44323 45355 52453 15115 31451 15144 52345 51244 41343 15113 24322 32434 45315 32341 55145 15154 13444 53242 41545 22115 21123 23345 53411 31351 15115 44231 53422 24455 51512 35151 34345 24453 21544 24334 31511 24115 24345 34554 51124 15351 11114 15451 14451 55341 21134 45343 44323 15553 12124 11431 53513 23322 42153 45441 41515 55454 54535 43313 23324 45522 41122 15212 13523 35354 52334 45433 51415 15111 12423 15214 52452 35555 145
\ No newline at end of file
diff --git a/2021/plaintext.8a.txt b/2021/plaintext.8a.txt
new file mode 100644 (file)
index 0000000..c409609
--- /dev/null
@@ -0,0 +1,24 @@
+well that was a surprise i found the attached letter on my doormat in a copy of the local magazine
+it was clever really there is no way to trackback to how it got there and no point in wasting time
+or resources trying to find out in any case it was clear that trinity sent it and equally clear what
+she wanted even the cipher they have used is a message to me it is double encrypted with the second
+stage using the same polybius grid i used for my last diary entry they are telling me that i have
+nowhere to hide once i stripped that off i was left with a standard but tricky cipher to break
+fortunately i learned the dark arts of frequency analysis and cribbing from harry so it didnt take
+long to crack it the second surprise is that i dont know what to do normally any unsolicited
+approach like this would be instantly reported to the lamplighters so they could investigate but as
+trinity points out i had already concealed the last intercept from harry worried that it might
+damage his trust in me it will not look good if he finds that out from them but if i tell him then i
+will also have to tell him about this direct appeal to join them i dont think that will make things
+any better between us there is something else too the founders of the conspiracy are personal heroes
+of mine and icant bear to think that they might have been working for the darkside if it is true
+then i would rather find out for myself than leave it to others in boss i suppose i could tell all
+and offer to infiltrate the agency but the history of double agents is not a happy one it is hard to
+really trust someone who has worked for the opposition even if they do it undercover too many have
+been corrupted by the compromises required and i am not sure i am cutout for that sort of work i
+dont think harry would insist but i am certain somebody in boss would the talk of the pandemic and
+cop will be a red flag and someone somewhere will be desperate to break into the conspiracy
+desperate enough to make mean offer icant refuse i will have to take this further but before i agree
+to meet trinity i need to know more the name of the souter point lighthouse rings a bell but icant
+remember where i came across it i will have to get the trainees to figure out why it might be
+important meanwhile i have another more urgent trip to make to mass our ie
\ No newline at end of file