Done challenge 5
authorNeil Smith <neil.git@njae.me.uk>
Fri, 12 Nov 2021 15:07:12 +0000 (15:07 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 12 Nov 2021 15:07:12 +0000 (15:07 +0000)
2021/2021-challenge5.ipynb [new file with mode: 0644]
2021/2021-challenge5.md [new file with mode: 0644]
2021/ciphertext.5a.txt [new file with mode: 0644]
2021/ciphertext.5b.txt [new file with mode: 0644]
2021/plaintext.5a.txt [new file with mode: 0644]
2021/plaintext.5b.txt [new file with mode: 0644]

diff --git a/2021/2021-challenge5.ipynb b/2021/2021-challenge5.ipynb
new file mode 100644 (file)
index 0000000..d6bf264
--- /dev/null
@@ -0,0 +1,503 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "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.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 = 5\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": 5,
+   "id": "0f1f792a",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\n",
+    "\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "b8d5f9ec-27f1-498b-8e64-c5eb2424e581",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'j': 2,\n",
+       "         'n': 145,\n",
+       "         'o': 133,\n",
+       "         'c': 61,\n",
+       "         't': 202,\n",
+       "         'h': 106,\n",
+       "         'l': 74,\n",
+       "         'b': 25,\n",
+       "         'i': 152,\n",
+       "         'w': 44,\n",
+       "         'e': 241,\n",
+       "         'v': 20,\n",
+       "         's': 101,\n",
+       "         'r': 94,\n",
+       "         'a': 162,\n",
+       "         'm': 36,\n",
+       "         'u': 60,\n",
+       "         'g': 48,\n",
+       "         'y': 35,\n",
+       "         'd': 67,\n",
+       "         'f': 35,\n",
+       "         'k': 17,\n",
+       "         'p': 18,\n",
+       "         'x': 4,\n",
+       "         'z': 1})"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sca_counts = collections.Counter(sca)\n",
+    "sca_counts"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "b5cabba1-ac75-46ea-ac05-8699cc88d986",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<AxesSubplot:>"
+      ]
+     },
+     "execution_count": 21,
+     "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": 28,
+   "id": "61ce2102-294e-4b1a-842c-1607aa7a4b05",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "5 \n",
+      "\n",
+      "jodieicanseewhyyouareconcernedbutifindithardtobelievethatagathacouldhavebeenpartofaconspiracyshewasafaithfulcolleagueinallthetimeiworkedwithherandnooneeversuggestedotherwiseofcoursewerantheusualspotchecksfromtimetotimebutnothingunusualwasfoundhavingsaidthatthemessageyoufoundinthearchiveisreallyworryingmyfirstthoughtwasthatshemighthavebeenactingasadoubleagenttryingtodestabilisenaziintelligencebutthatdoesntfitwiththetextitiscrucialtoourmissionthatwemaintainthebalanceofuncertaintyanddirectittoouradvantagemakeitlooklikeshehaddefinitelyhadanotheragendaitrawledthroughmyownrecordstoseeifanyoneelseagathaandiworkedwithmighthavebeeninvolvedihatetosayitbuttheonlypersonofinterestatthemomentischarlieweworkedtogetheronthekohinoortwinscaseandagathawashergreatauntnotthattreacheryisagenetictraitbutinvettingcirclesitcanbetreatedlikeitisinheritedsoisupposeweoughttotakethatseriouslyespeciallysinceshebecameprettyseniorinamericanintelligenceicheckedourcurrentcasefilesandalthoughsheisretiredshestillactsasgovernmentliaisonsheisinlondonatthemomentinthenewembassybuildingwhichwillmakeitdifficulttogetholdofherifshewantstostayhiddenwecantaffordtoupsetouruscousinsandifwearewrongaboutherwemightalsopoisonthewellwhenitcomestointelligenceexchangetheyhaventforgivenusforphilbyandmacleanyetsoicanimaginehowtheywouldreactifitturnsoutthatoneofourownisadoubleagentandhasinfiltratedtheirinnersanctumisentoneoftheelvestotakealookatherapartmentinnewjerseyitwasprettycleanasyoucanimaginebuttheywereabletoliftthefollowingextractitwashardtoreadandevenhardertodeciphersincesheusedavigenereencryptionbutoneincriminatingfeaturestandsoutevenwithoutadecryptsheusedtheadmorseencodingontopofthevigenerecipheriamnotsurewhatweshoulddonextcouldyougettheteamtotakealookatthefilemaybethisisallabigcoincidenceoramisunderstandingifnotthenwemayhavetotelllondonandwashingtonandiamreallynotlookingforwardtothatallthebestharry\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_a, score_a = railfence_break(sca, fitness=Ptrigrams)\n",
+    "print(key_a, '\\n')\n",
+    "pa = railfence_decipher(sca, key_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "605792ee-8bbf-44da-b33f-6bd2321f449e",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(0, 1, 2, 3) False True \n",
+      "\n",
+      "sichacnerlliitniyicaiemanorianesletthpemhbecnhseesinrllacpecaeylhioulestkethtatohghtdoewnpossusiredsiirersinhtieodlietaeebethactdleswricstinuevntbutniarnticnnegiyishehcetretahtetnoeuatsgrerehsohawtagabeanhacsgtwiooonckohahtnehernegorkedlowesliefahcsntismometthttsehnteafonsersfylntthetubtesayetetidihivloeninyebefthargimhwitaekrediwiaahtagaesleiyonhafihoseosdrfrecswoyoughdrhtawleirtisendfarelnottdahdtellnifgaddyehseliknooltkeinmegoantedarstooiitcrdirhnaylainireceofudcnaeebaetnirintimewrthaeoisyrmisootrciakrcsutitpetetthtiwtiesntnodtctthtbectigeeletrziitnesnbilrtsetgtosiyrrenteaeltdoursagrctieneeaaveithgphemttahowasehguetthhrifdngmnyrrelywnaertveinhcrotheaidngufoayegiesshehtkthaaiasvvinthdndsfotwlaenushgnianotnubeuotiuemixromiskcetchupsllusuahtnawernsrugofcasiwathehdetsggetsresneeiondleraihtinkedoowimtimdhtlainaaugauolltluftaitfasaosheecarenspecafoartuneeoavehdlurhaceagaethacveifobeydraoditpifihdbutnreecontraunhyyeeeseicawidoeyrrthahebetlltotahldtoeawrnngfakoonnottllaeamrndnaagtosihsnndwcnodslloyetohaveayamaenwgttocgiflidnarstodnupamigoecpidednioobigellayisiotebeematifefattmooloakepotmeeteettenyoucluorextnodddhouiewtgewhfustoamnerehbecinenenevietfoyntongnirncoaesraadmehtdoeuststpnecreatunithtnevuoutodnaoresstaeiinguaniocriiienebutmoithcryeeerngentvadeeuslsecersihhpitodesredenhabvedradaarotsharpawtfactntxetwinwllohtheefililetkaerceywlttubinetamimucadysaeleaiyttesprcwtihrserjweutinaemtaapacehteookgaekntotnevlytheaoencentiimusancarentiriehtdorathlifkasirdnaigengelbiadotinwaouraoenthatatuoaurndtifnactirdloywothtwwnehsgamecanrostoanyolcaiandablivorpvsunhgivoofttaveeyehengeohcxmncedgilantehotsycomeineellwtwehasonuopoetaltgimnerwltuoangatrweswealidniinshuocfuruatesntounrofintadcewtddebhyantosbtnaishetireodofyohtotogslucaiffutiealmatiwhgwhiunidubuihssamwemtnehetinaemoatheoanorlonsisivnshnsiawntlemnrlgoveasthllawtseiedsoitebeisoshgttholadnhlestfescntcorrunourjekc \n"
+     ]
+    }
+   ],
+   "source": [
+    "(word_a, fill_a, empty_a), score_a = column_transposition_break(rsca, fitness=Ptrigrams)\n",
+    "print(word_a, fill_a, empty_a, '\\n')\n",
+    "pa = column_transposition_decipher(rsca, word_a, fillcolumnwise=fill_a, emptycolumnwise=empty_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "c3cccd86-5e40-4040-8f91-9ca53ac6e909",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "a KeywordWrapAlphabet.from_a \n",
+      "\n",
+      "jnocthltoboiwhelewnvsroaaetmhuugtauasoyotibnbtdinnafhilstalnteuateeyhadmoeetohvvaiooreswtoindaataatigirkhoetasicaynngecaaurhceiedmtblckiehwtnfpsarbestheletnehmeiouisooutnentoeaarnyennbeofgidnrcneepomfteoyeodpgpoalcgaahyscnsanetnanelothroasyuneuitaeiaacueetfpreatflaalmidiadeeetewcurnulhcmiietisaonnsatsgonerirwrmfhushmgeeigultroelsitechttitetsatisawtiaaucnyrcortgilksdflhtediethycreineahwrtmaenohtytensneehmiceedornhnisnawsetotecsgcrtnncstteienesiswtohtulcanecmtsiaaiiehcrucssnogseseatvrlahinoeonhmaidihaefcgtfeeasaewafusucsnaeaowmlonhwemselexehetvnpidaytnmhwoltfnotnrwobnaiftdincutneltkktatneeirtaaaieuwrtleonettrtadadeiicsdnryttniigesatvhurpsdmroiooieihnthtudtoueemelteabiagoeciutnfowmeoodwsoaratofrohteardceyaorbfirbehgalverasahsiulgntiwetrnergehifretssckomtbonulfdiahhsefdhceeyrgitgaaehvetaoenytsieiegetdnthticiomihennbnfeiaitoaneeoihdieaorntlhgoedsfolgaikiihbilieabhlrotstothiwegetoowcagahranhrhieiauviiecealiirdsoehttsoyeliseetermcnlnckurteedhhitdslsontissonhmieesuihwmifuohorhnoydetooerondewguriapoelnotticcgevfiurlncnsaaetwdciruaeundlensiatrenmnehvoeohpmiwstptescmntyeeihlixcwaodehedpseuaeeriuernnaenuettctutdscntfvncemswwodxuotttkotfmesliidemnsditnavtlodhtnmloogwtalbhyiiehrcndiddovtahdanacncsaalouihtokheonsgdtsoswhuptsreoungnwshviteeyuithvalynrthwthtancsdaeigtbnzlibtoswtetrcorotmitecoranditdamkoleantdnaerwruwrsoaysaadewgtenvdtsutyefnttmnalokehhkotaeahegutateyntibetrlabtdtsieupogaeeieplshbpenoeitlcieornflatseietlagmnsnilatetnwsbnwiltiltodistthdcnrttuuiiwrntegtoswlicongnhnyaogsobalaocgnhyratuthooiaegdalrhiraieotetaoeaetjrwsylyuaitealftlwtaahravnrohrsevgecobicaitrdoniaesehaengnteeeraueehoelyteoaoaietilbnioadrigteyaelnnigdalnknadtleteweentethpoyfceerhouoeeeofttuaadmonilistshaagnaalueixuunahetdtvakhiagaontnendheeotpiaerrterstrntrettcneitpukrsyerireedeilhriseontneygldtlfsiadosfohhietieahrfyeiieettfsahtessfslrneacoghbtorseetehinnntuswdheeohrirsndhtklhacrenhhlaniyiras\n"
+     ]
+    }
+   ],
+   "source": [
+    "(word_a, wrap_a), score_a = keyword_break(sca, fitness=Pletters)\n",
+    "print(word_a, wrap_a, '\\n')\n",
+    "pa = keyword_decipher(sca, word_a, wrap_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "47bfce9d-9932-457f-a175-715660ac9d01",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "okhltfwynjvdgsiuqraecbpxmz \n",
+      "\n",
+      "jiauecdeavaogctdtgiknrassteycppmespsnahaeoviveloiisfcodnesdietpsetthcslyatteackksoaartngeaoilssesseomorbcatesnoushiimtussprcutotlyevdubotcgeifwnsrvtnectdteitcytoaponaapeitieatssrihtiivtafmoliruittwayfetahtalwmwasdumsschnuinsiteisitdaecrasnhpitpoestossupttefwrtsefdssdyolosltttetgupripdcuyooteonsaiinsenmaitrorgryfcpncymttompderatdnoetuceeoetenseonsgeosspuihruaremodbnlfdcetlotechurtoitscgreystiacehetinittcyouttlaricionisgnteaetunmureiiuneetotitnongeacepdusituyenossootcurpunniamntntsekrdscoiataicysolocstfumefttsnstgsfpnpunistsagydaicgtyntdtxtctekiwolsheiycgadefiaeirgavisofeloiupeitdebbeseittoresssotpgredtaiteereslsltoounlirheeioomtnsekcprwnlyraoaaotociecepleapttytdetsvosmatuopeifagytaalgnasrseafracetsrluthsarvforvtcmsdktrsnscnopdmieogteritrmtcofrtennubayevaipdflosccntflcutthrmoemsstcktesatihenototmtelieceouoayoctiiviftosoeasittaoclotsariedcmatlnfadmsoboocvodotsvcdraeneaecogtmteaagusmscrsicrcotospkootutsdoorlnatceenahtdonttetryuidiubprettlccoelndnaieonnaicyottnpocgyofpacarciahlteaatrailtgmproswatdiaeeouumtkfoprdiuinsstegluorpstpildtinosertiyitckatacwyognewetnuyiehttocdoxugsaltctlwntpsttroptriistipteeuepelnuiefkiutynggalxpaeeebaefytndooltyinloeiskedalceiydaamgesdvchootcruilollakesclsisuiunssdapoceabctainmlenangcpwenrtapimignckoetthpoecksdhirecgecesiunlstomevizdoveangeteruaraeyoetuarsiloelsybadtsielistrgrpgrnashnssltgmetiklenpehtfieeyisdabtccbaestsctmpesethieovterdsvelenotpwamsttotwdncvwtiatoeduotarifdsentotedsmyiniodseteignvigodeodealoneecluireeppoogrietmeangdouaimicihsamnavsdsaumichrsepecaaostmlsdrcorsotaetesatstejrgnhdhpsoetsdfedgesscrskiracrntkmtuavousoerlaiostntcstimietttrspttcatdhetasasoteodvioaslromethstdiiomlsdibisledtetgttietecwahfuttrcapatttafeepsslyaiodonencssmissdptoxppiscteleksbcosmsaieitilcttaewostrretrnerierteeuitoewpbrnhtrorttltodcrontaieithmdledfnoslanfaccoteotscrfhtootteefnscetnnfndritsuamcvearnttetcoiiiepnglcttacrornilcebdcsurticcdsiohorsn\n"
+     ]
+    }
+   ],
+   "source": [
+    "word_a, score_a = monoalphabetic_sa_break(sca)\n",
+    "print(word_a, '\\n')\n",
+    "pa = keyword_decipher(sca, word_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "d925f1d9-f70b-4858-85ba-8eb1ae919080",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "a \n",
+      "\n",
+      "jnocthltoboiwhelewnvsroaaetmhuugtauasoyotibnbtdinnafhilstalnteuateeyhadmoeetohvvaiooreswtoindaataatigirkhoetasicaynngecaaurhceiedmtblckiehwtnfpsarbestheletnehmeiouisooutnentoeaarnyennbeofgidnrcneepomfteoyeodpgpoalcgaahyscnsanetnanelothroasyuneuitaeiaacueetfpreatflaalmidiadeeetewcurnulhcmiietisaonnsatsgonerirwrmfhushmgeeigultroelsitechttitetsatisawtiaaucnyrcortgilksdflhtediethycreineahwrtmaenohtytensneehmiceedornhnisnawsetotecsgcrtnncstteienesiswtohtulcanecmtsiaaiiehcrucssnogseseatvrlahinoeonhmaidihaefcgtfeeasaewafusucsnaeaowmlonhwemselexehetvnpidaytnmhwoltfnotnrwobnaiftdincutneltkktatneeirtaaaieuwrtleonettrtadadeiicsdnryttniigesatvhurpsdmroiooieihnthtudtoueemelteabiagoeciutnfowmeoodwsoaratofrohteardceyaorbfirbehgalverasahsiulgntiwetrnergehifretssckomtbonulfdiahhsefdhceeyrgitgaaehvetaoenytsieiegetdnthticiomihennbnfeiaitoaneeoihdieaorntlhgoedsfolgaikiihbilieabhlrotstothiwegetoowcagahranhrhieiauviiecealiirdsoehttsoyeliseetermcnlnckurteedhhitdslsontissonhmieesuihwmifuohorhnoydetooerondewguriapoelnotticcgevfiurlncnsaaetwdciruaeundlensiatrenmnehvoeohpmiwstptescmntyeeihlixcwaodehedpseuaeeriuernnaenuettctutdscntfvncemswwodxuotttkotfmesliidemnsditnavtlodhtnmloogwtalbhyiiehrcndiddovtahdanacncsaalouihtokheonsgdtsoswhuptsreoungnwshviteeyuithvalynrthwthtancsdaeigtbnzlibtoswtetrcorotmitecoranditdamkoleantdnaerwruwrsoaysaadewgtenvdtsutyefnttmnalokehhkotaeahegutateyntibetrlabtdtsieupogaeeieplshbpenoeitlcieornflatseietlagmnsnilatetnwsbnwiltiltodistthdcnrttuuiiwrntegtoswlicongnhnyaogsobalaocgnhyratuthooiaegdalrhiraieotetaoeaetjrwsylyuaitealftlwtaahravnrohrsevgecobicaitrdoniaesehaengnteeeraueehoelyteoaoaietilbnioadrigteyaelnnigdalnknadtleteweentethpoyfceerhouoeeeofttuaadmonilistshaagnaalueixuunahetdtvakhiagaontnendheeotpiaerrterstrntrettcneitpukrsyerireedeilhriseontneygldtlfsiadosfohhietieahrfyeiieettfsahtessfslrneacoghbtorseetehinnntuswdheeohrirsndhtklhacrenhhlaniyiras\n"
+     ]
+    }
+   ],
+   "source": [
+    "word_a, score_a = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "print(word_a, '\\n')\n",
+    "pa = vigenere_decipher(sca, word_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "c7f2e770-8062-4d18-b90a-cb2e410ef88c",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "jodie i can see why you are concerned but i find it hard to believe that agatha could have been part\n",
+      "of a conspiracy she was a faithful colleague in all the time i worked with her and no one ever\n",
+      "suggested otherwise of course we ran the usual spot checks from time to time but nothing unusual was\n",
+      "found having said that the message you found in the archive is really worrying my first thought was\n",
+      "that she might have been acting as a double agent trying to destabilise nazi intelligence but that\n",
+      "doesnt fit with the text it is crucial to our mission that we maintain the balance of uncertainty\n",
+      "and direct it to our advantage make it look like she had definitely had another agenda i trawled\n",
+      "through my own records to see if anyone else agatha and i worked with might have been involved i\n",
+      "hate to say it but the only person of interest at the moment is charlie we worked together on the\n",
+      "kohinoor twins case and agatha washer great aunt not that treachery is a genetic trait but in\n",
+      "vetting circles it can be treated like it is inherited so i suppose we ought to take that seriously\n",
+      "especially since she became pretty senior in american intelligence i checked our current case files\n",
+      "and although she is retired she still acts as government liaison she is in london at the moment in\n",
+      "the new embassy building which will make it difficult to get hold of her if she wants to stay hidden\n",
+      "we cant afford to upset our us cousins and if we are wrong about her we might also poison the well\n",
+      "when it comes to intelligence exchange they havent for given us for phil by and maclean yet so i can\n",
+      "imagine how they would react if it turns out that one of our own is a double agent and has\n",
+      "infiltrated their inner sanctum i sent one of the elves to take a look at her apartment in new\n",
+      "jersey it was pretty clean as you can imagine but they were able to lift the following extract it\n",
+      "was hard to read and even harder to decipher since she used avi genere encryption but one\n",
+      "incriminating feature stands out even without a decrypt she used the ad morse encoding on top of the\n",
+      "vi genere cipher i am not sure what we should do next could you get the team to take a look at the\n",
+      "file maybe this is all a big coincidence or a misunderstanding if not then we may have to tell\n",
+      "london and washington and i am really not looking forward to that all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = railfence_decipher(sca, key_a)\n",
+    "print(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "6cecddd9",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2333"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "id": "77e0eb5c-226d-4197-a687-4a5d725c6af0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "morse_chars = 'a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9'.split()\n",
+    "# morse_chars"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "0c7912fb-f552-4933-9730-3784197fc729",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "morse_codes = '.- / -... / -.-. / -.. / . / ..-. / --. / .... / .. / .--- / -.- / .-.. / -- / -. / --- / .--. / --.- / .-. / ... / - / ..- / ...- / .-- / -..- / -.-- / --.. / ----- / .---- / ..--- / ...-- / ....- / ..... / -.... / --... / ---.. / ----.'.split(' / ')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "ae62967b-0c5d-4e14-adf2-8cad03ed6970",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['.-', '-...', '-.-.']"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "char_to_morse = {l: c for l, c in zip(morse_chars, morse_codes)}\n",
+    "morse_to_char = {c: l for l, c in zip(morse_chars, morse_codes)}\n",
+    "[char_to_morse[l] for l in 'abc']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "d5c24bcb-fda8-40f0-89ba-166380046fc9",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'cdbaneliksgsaztmemhewdmgmydbanadbwyxbuxtynnzelojgrnyhlhyvcyhnrimsynckcifyjyifyjagyhlhuqisnxrunemdcdlhynxolgujdynukugwujynyokhybyannrymscmuftlsmcmuucfgyxkmilsyktbbimgbdbwumeudcbkhfefcvmtcdbanegyfeynngihfyktcquleckgvimkjhocxnwdnrultbonjihsnqtykgdezdzalyccftbovssywyftqryftboskhczjwdientundbwyxsxfonruneuvilozgujncxasnxkndeucnlhyixgnncywmnybsvyvyxtuxslhcxauulbyftzylzalbslozshvizdbwybkxzeqyoddhdbsvyzuksynnzecxpwsnsastcyhlonrysrwruwofyaasncclwiefvhufyyohomlrusaztozmlacbmxolkwliixcsmcxnoogshvsulimtcdcxahiifeyvmwwuccfvycnagudcfgcgimlxcuqwycbgufncynibyatnryqalooflcuydynygskywouhipuzimdijiwkfuulsikinivmtcpufyixyuoovxlrumylhyvcfknyoknignzehrujrskhvjincwalonzeixyktiniatdyxaecculelbcwrqrioohdfwtuxslhcxayoixwwsbobssbolleydbannyclahnbsrlibssvoyfalyofdfyhyehyoyhnyefoqgbwnmygwtbshytlspaafsmscneudlssgholduftixvsluxwwinrcfkcgcdlhoyvtilygnnryyriehvwbolwiwkhzojongihpfmehmylhyncjewdcgnipnzecbyfqoslaempijtboagoxyzwvybsgnygyfeynngkyojsvybsdoqzlgfcvystfouktqrcdenrytomccfvycnagudcgnccbgtmyoflycmlhycsktywzdaacujeuvwjimsmoeqsfdhufyloxsuddighgulkwlipsnaempijaqrcdeqoqalfmujrsyhoinrzgrymuktmlolwcvffonkwlohdbwmoxfwsmdbwtbbystfopwllsmwsnynwnyfyftbohlhymojiugcdlhoyvtiwywtnyxwccnyohydbwrcdckwccylonkewawdcgncgcdlbouvtivifdixngtuuyuhubawozwckdcbyutcyhqoomufcixnscnwystnrywmvkmkywrujlco'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "morse_table = ''.maketrans('AD', '.-')\n",
+    "cb_dd = cb.translate(morse_table)\n",
+    "cb_words = cb_dd.split(' / ')\n",
+    "cb_letters = cat(cat(morse_to_char[l] for l in w.split()) for w in cb_words)\n",
+    "cb_letters"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "id": "16210c33-3bcb-43c8-9189-d82eea7cf53b",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "ukusa \n",
+      "\n",
+      "ithinkbossmightsuspectsomethingtheydraftedthereportonthelighthousediscoveryoveramonthagoandhavestillnotforwardedasummarytoushereintheusicantriskmakingenquiriesthroughtheusualchannelsbutithinkweneedtoinvestigateiamdisappointedthatthetrinityteamleftfilesinthebasementwhentheyshippedoutbuttheydidnothavealotofwarningandatleasttheydontseemtohaveleftanythingcurrentforharrytofindiftheyhadhewouldnthavepassedtheinvestigationtothearchaeologistsitwouldhavegonestraightupstairsforactioniamintwomindsaboutitifanyoneelsewasinvestigatingiwouldsayweshouldignoreittheyareunlikelytomakemuchofahistoricalcuriositybutifanyonecouldtracethelinktousnowthenharryandjodiearetheonestodoitjodieisaterrierwhowontletanythinggoonceshehasherteethintoitandharryhasbeenaroundlongenoughtoknowwhensomethingtrivialisactuallyimportantonbalanceithinkiwillneedtobeonthegroundwhereicanhopetoinfluencethedirectionoftheirenquiriesforthegoodofeveryoneweneedtokeepaverylowprofileatleastwhilethebossinvestigationishotsounlessthesystemflagsarealcrisiswewillhavetodialdownouractivitiesforawhilewewillcarryonwithforecastsbutwillnotactonthemunlessthethreatlevelrisestoteneventhenthecuriawillneedtomeettodecidewhetheritiswisetotakeactioniwillheadtolondontotakechargeofmisdirectionyoucancontactmeattheembassycharlie\n"
+     ]
+    }
+   ],
+   "source": [
+    "word_b, score_b = vigenere_frequency_break(cb_letters, fitness=Ptrigrams)\n",
+    "print(word_b, '\\n')\n",
+    "pb = vigenere_decipher(cb_letters, word_b)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "id": "fe094361-7c85-40d9-952e-0c84abbcf903",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "i think boss might suspect something they drafted the report on the lighthouse discovery over a\n",
+      "month ago and have still not forwarded a summary to us herein the us icant risk making enquiries\n",
+      "through the usual channels but i think we need to investigate i am disappointed that the trinity\n",
+      "team left files in the basement when they shipped out but they did not have alot of warning and\n",
+      "atleast they dont seem to have left anything current for harry to find if they had he wouldnt have\n",
+      "passed the investigation to the archaeologists it would have gone straight upstairs for action i am\n",
+      "in two minds about it if anyone else was investigating i would say we should ignore it they are\n",
+      "unlikely to make much of a historical curiosity but if anyone could trace the link to us now then\n",
+      "harry and jodie are the ones to do it jodie is a terrier who wont let anything go once she has her\n",
+      "teeth into it and harry has been around long enough to know when something trivial is actually\n",
+      "important on balance i think i will need to be on the ground where i can hope to influence the\n",
+      "direction of their enquiries for the good of everyone we need to keep a very low profile atleast\n",
+      "while the boss investigation is hot so unless the system flags a real crisis we will have to dial\n",
+      "down our activities for a while we will carry on with forecasts but will not acton them unless the\n",
+      "threat level rises to ten even then the curia will need to meet to decide whether it is wise to take\n",
+      "action i will head to london to take charge of misdirection you can contact meat the embassy charlie\n"
+     ]
+    }
+   ],
+   "source": [
+    "pb = vigenere_decipher(cb_letters, word_b)\n",
+    "print(prettify(pb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "d12a663c",
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1563"
+      ]
+     },
+     "execution_count": 40,
+     "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-challenge5.md b/2021/2021-challenge5.md
new file mode 100644 (file)
index 0000000..c0a093f
--- /dev/null
@@ -0,0 +1,143 @@
+---
+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.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 = 5
+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()
+cb = open(ciphertext_b_filename).read()
+
+sca = sanitise(ca)
+rsca = cat(reversed(sca))
+scb = sanitise(cb)
+```
+
+```python
+sca_counts = collections.Counter(sca)
+sca_counts
+```
+
+```python
+pd.Series(sca_counts).sort_index().plot.bar()
+```
+
+```python
+key_a, score_a = railfence_break(sca, fitness=Ptrigrams)
+print(key_a, '\n')
+pa = railfence_decipher(sca, key_a)
+print(pa)
+```
+
+```python
+(word_a, fill_a, empty_a), score_a = column_transposition_break(rsca, fitness=Ptrigrams)
+print(word_a, fill_a, empty_a, '\n')
+pa = column_transposition_decipher(rsca, word_a, fillcolumnwise=fill_a, emptycolumnwise=empty_a)
+print(pa)
+```
+
+```python
+(word_a, wrap_a), score_a = keyword_break(sca, fitness=Pletters)
+print(word_a, wrap_a, '\n')
+pa = keyword_decipher(sca, word_a, wrap_a)
+print(pa)
+```
+
+```python
+word_a, score_a = monoalphabetic_sa_break(sca)
+print(word_a, '\n')
+pa = keyword_decipher(sca, word_a)
+print(pa)
+```
+
+```python
+word_a, score_a = vigenere_frequency_break(sca, fitness=Ptrigrams)
+print(word_a, '\n')
+pa = vigenere_decipher(sca, word_a)
+print(pa)
+```
+
+```python
+pa = railfence_decipher(sca, key_a)
+print(prettify(pa))
+```
+
+```python Collapsed="false"
+open(plaintext_a_filename, 'w').write(prettify(pa))
+```
+
+```python
+morse_chars = 'a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9'.split()
+# morse_chars
+```
+
+```python
+morse_codes = '.- / -... / -.-. / -.. / . / ..-. / --. / .... / .. / .--- / -.- / .-.. / -- / -. / --- / .--. / --.- / .-. / ... / - / ..- / ...- / .-- / -..- / -.-- / --.. / ----- / .---- / ..--- / ...-- / ....- / ..... / -.... / --... / ---.. / ----.'.split(' / ')
+```
+
+```python
+char_to_morse = {l: c for l, c in zip(morse_chars, morse_codes)}
+morse_to_char = {c: l for l, c in zip(morse_chars, morse_codes)}
+[char_to_morse[l] for l in 'abc']
+```
+
+```python
+morse_table = ''.maketrans('AD', '.-')
+cb_dd = cb.translate(morse_table)
+cb_words = cb_dd.split(' / ')
+cb_letters = cat(cat(morse_to_char[l] for l in w.split()) for w in cb_words)
+cb_letters
+```
+
+```python
+word_b, score_b = vigenere_frequency_break(cb_letters, fitness=Ptrigrams)
+print(word_b, '\n')
+pb = vigenere_decipher(cb_letters, word_b)
+print(pb)
+```
+
+```python
+pb = vigenere_decipher(cb_letters, word_b)
+print(prettify(pb))
+```
+
+```python Collapsed="false"
+open(plaintext_b_filename, 'w').write(prettify(pb))
+```
+
+```python Collapsed="false"
+
+```
diff --git a/2021/ciphertext.5a.txt b/2021/ciphertext.5a.txt
new file mode 100644 (file)
index 0000000..987a8d8
--- /dev/null
@@ -0,0 +1 @@
+JNOCT HLTOB OIWHE LEWNV SROAA ETMHU UGTAU ASOYO TIBNB TDINN AFHIL STALN TEUAT EEYHA DMOEE TOHVV AIOOR ESWTO INDAA TAATI GIRKH OETAS ICAYN NGECA AURHC EIEDM TBLCK IEHWT NFPSA RBEST HELET NEHME IOUIS OOUTN ENTOE AARNY ENNBE OFGID NRCNE EPOMF TEOYE ODPGP OALCG AAHYS CNSAN ETNAN ELOTH ROASY UNEUI TAEIA ACUEE TFPRE ATFLA ALMID IADEE ETEWC URNUL HCMII ETISA ONNSA TSGON ERIRW RMFHU SHMGE EIGUL TROEL SITEC HTTIT ETSAT ISAWT IAAUC NYRCO RTGIL KSDFL HTEDI ETHYC REINE AHWRT MAENO HTYTE NSNEE HMICE EDORN HNISN AWSET OTECS GCRTN NCSTT EIENE SISWT OHTUL CANEC MTSIA AIIEH CRUCS SNOGS ESEAT VRLAH INOEO NHMAI DIHAE FCGTF EEASA EWAFU SUCSN AEAOW MLONH WEMSE LEXEH ETVNP IDAYT NMHWO LTFNO TNRWO BNAIF TDINC UTNEL TKKTA TNEEI RTAAA IEUWR TLEON ETTRT ADADE IICSD NRYTT NIIGE SATVH URPSD MROIO OIEIH NTHTU DTOUE EMELT EABIA GOECI UTNFO WMEOO DWSOA RATOF ROHTE ARDCE YAORB FIRBE HGALV ERASA HSIUL GNTIW ETRNE RGEHI FRETS SCKOM TBONU LFDIA HHSEF DHCEE YRGIT GAAEH VETAO ENYTS IEIEG ETDNT HTICI OMIHE NNBNF EIAIT OANEE OIHDI EAORN TLHGO EDSFO LGAIK IIHBI LIEAB HLROT STOTH IWEGE TOOWC AGAHR ANHRH IEIAU VIIEC EALII RDSOE HTTSO YELIS EETER MCNLN CKURT EEDHH ITDSL SONTI SSONH MIEES UIHWM IFUOH ORHNO YDETO OERON DEWGU RIAPO ELNOT TICCG EVFIU RLNCN SAAET WDCIR UAEUN DLENS IATRE NMNEH VOEOH PMIWS TPTES CMNTY EEIHL IXCWA ODEHE DPSEU AEERI UERNN AENUE TTCTU TDSCN TFVNC EMSWW ODXUO TTTKO TFMES LIIDE MNSDI TNAVT LODHT NMLOO GWTAL BHYII EHRCN DIDDO VTAHD ANACN CSAAL OUIHT OKHEO NSGDT SOSWH UPTSR EOUNG NWSHV ITEEY UITHV ALYNR THWTH TANCS DAEIG TBNZL IBTOS WTETR COROT MITEC ORAND ITDAM KOLEA NTDNA ERWRU WRSOA YSAAD EWGTE NVDTS UTYEF NTTMN ALOKE HHKOT AEAHE GUTAT EYNTI BETRL ABTDT SIEUP OGAEE IEPLS HBPEN OEITL CIEOR NFLAT SEIET LAGMN SNILA TETNW SBNWI LTILT ODIST THDCN RTTUU IIWRN TEGTO SWLIC ONGNH NYAOG SOBAL AOCGN HYRAT UTHOO IAEGD ALRHI RAIEO TETAO EAETJ RWSYL YUAIT EALFT LWTAA HRAVN ROHRS EVGEC OBICA ITRDO NIAES EHAEN GNTEE ERAUE EHOEL YTEOA OAIET ILBNI OADRI GTEYA ELNNI GDALN KNADT LETEW EENTE THPOY FCEER HOUOE EEOFT TUAAD MONIL ISTSH AAGNA ALUEI XUUNA HETDT VAKHI AGAON TNEND HEEOT PIAER RTERS TRNTR ETTCN EITPU KRSYE RIREE DEILH RISEO NTNEY GLDTL FSIAD OSFOH HIETI EAHRF YEIIE ETTFS AHTES SFSLR NEACO GHBTO RSEET EHINN NTUSW DHEEO HRIRS NDHTK LHACR ENHHL ANIYI RAS
diff --git a/2021/ciphertext.5b.txt b/2021/ciphertext.5b.txt
new file mode 100644 (file)
index 0000000..d53e46a
--- /dev/null
@@ -0,0 +1 @@
+DADA DAA DAAA AD DA A ADAA AA DAD AAA DDA AAA AD DDAA D DD A DD AAAA A ADD DAA DD DDA DD DADD DAA DAAA AD DA AD DAA DAAA ADD DADD DAAD DAAA AAD DAAD D DADD DA DA DDAA A ADAA DDD ADDD DDA ADA DA DADD AAAA ADAA AAAA DADD AAAD DADA DADD AAAA DA ADA AA DD AAA DADD DA DADA DAD DADA AA AADA DADD ADDD DADD AA AADA DADD ADDD AD DDA DADD AAAA ADAA AAAA AAD DDAD AA AAA DA DAAD ADA AAD DA A DD DAA DADA DAA ADAA AAAA DADD DA DAAD DDD ADAA DDA AAD ADDD DAA DADD DA AAD DAD AAD DDA ADD AAD ADDD DADD DA DADD DDD DAD AAAA DADD DAAA DADD AD DA DA ADA DADD DD AAA DADA DD AAD AADA D ADAA AAA DD DADA DD AAD AAD DADA AADA DDA DADD DAAD DAD DD AA ADAA AAA DADD DAD D DAAA DAAA AA DD DDA DAAA DAA DAAA ADD AAD DD A AAD DAA DADA DAAA DAD AAAA AADA A AADA DADA AAAD DD D DADA DAA DAAA AD DA A DDA DADD AADA A DADD DA DA DDA AA AAAA AADA DADD DAD D DADA DDAD AAD ADAA A DADA DAD DDA AAAD AA DD DAD ADDD AAAA DDD DADA DAAD DA ADD DAA DA ADA AAD ADAA D DAAA DDD DA ADDD AA AAAA AAA DA DDAD D DADD DAD DDA DAA A DDAA DAA DDAA AD ADAA DADD DADA DADA AADA D DAAA DDD AAAD AAA AAA DADD ADD DADD AADA D DDAD ADA DADD AADA D DAAA DDD AAA DAD AAAA DADA DDAA ADDD ADD DAA AA A DA D AAD DA DAA DAAA ADD DADD DAAD AAA DAAD AADA DDD DA ADA AAD DA A AAD AAAD AA ADAA DDD DDAA DDA AAD ADDD DA DADA DAAD AD AAA DA DAAD DAD DA DAA A AAD DADA DA ADAA AAAA DADD AA DAAD DDA DA DA DADA DADD ADD DD DA DADD DAAA AAA AAAD DADD AAAD DADD DAAD D AAD DAAD AAA ADAA AAAA DADA DAAD AD AAD AAD ADAA DAAA DADD AADA D DDAA DADD ADAA DDAA AD ADAA DAAA AAA ADAA DDD DDAA AAA AAAA AAAD AA DDAA DAA DAAA ADD DADD DAAA DAD DAAD DDAA A DDAD DADD DDD DAA DAA AAAA DAA DAAA AAA AAAD DADD DDAA AAD DAD AAA DADD DA DA DDAA A DADA DAAD ADDA ADD AAA DA AAA AD AAA D DADA DADD AAAA ADAA DDD DA ADA DADD AAA ADA ADD ADA AAD ADD DDD AADA DADD AD AD AAA DA DADA DADA ADAA ADD AA A AADA AAAD AAAA AAD AADA DADD DADD DDD AAAA DDD DD ADAA ADA AAD AAA AD DDAA D DDD DDAA DD ADAA AD DADA DAAA DD DAAD DDD ADAA DAD ADD ADAA AA AA DAAD DADA AAA DD DADA DAAD DA DDD DDD DDA AAA AAAA AAAD AAA AAD ADAA AA DD D DADA DAA DADA DAAD AD AAAA AA AA AADA A DADD AAAD DD ADD ADD AAD DADA DADA AADA AAAD DADD DADA DA AD DDA AAD DAA DADA AADA DDA DADA DDA AA DD ADAA DAAD DADA AAD DDAD ADD DADD DADA DAAA DDA AAD AADA DA DADA DADD DA AA DAAA DADD AD D DA ADA DADD DDAD AD ADAA DDD DDD AADA ADAA DADA AAD DADD DAA DADD DA DADD DDA AAA DAD DADD ADD DDD AAD AAAA AA ADDA AAD DDAA AA DD DAA AA ADDD AA ADD DAD AADA AAD AAD ADAA AAA AA DAD AA DA AA AAAD DD D DADA ADDA AAD AADA DADD AA DAAD DADD AAD DDD DDD AAAD DAAD ADAA ADA AAD DD DADD ADAA AAAA DADD AAAD DADA AADA DAD DA DADD DDD DAD DA AA DDA DA DDAA A AAAA ADA AAD ADDD ADA AAA DAD AAAA AAAD ADDD AA DA DADA ADD AD ADAA DDD DA DDAA A AA DAAD DADD DAD D AA DA AA AD D DAA DADD DAAD AD A DADA DADA AAD ADAA A ADAA DAAA DADA ADD ADA DDAD ADA AA DDD DDD AAAA DAA AADA ADD D AAD DAAD AAA ADAA AAAA DADA DAAD AD DADD DDD AA DAAD ADD ADD AAA DAAA DDD DAAA AAA AAA DAAA DDD ADAA ADAA A DADD DAA DAAA AD DA DA DADD DADA ADAA AD AAAA DA DAAA AAA ADA ADAA AA DAAA AAA AAA AAAD DDD DADD AADA AD ADAA DADD DDD AADA DAA AADA DADD AAAA DADD A AAAA DADD DDD DADD AAAA DA DADD A AADA DDD DDAD DDA DAAA ADD DA DD DADD DDA ADD D DAAA AAA AAAA DADD D ADAA AAA ADDA AD AD AADA AAA DD AAA DADA DA A AAD DAA ADAA AAA AAA DDA AAAA DDD ADAA DAA AAD AADA D AA DAAD AAAD AAA ADAA AAD DAAD ADD ADD AA DA ADA DADA AADA DAD DADA DDA DADA DAA ADAA AAAA DDD DADD AAAD D AA ADAA DADD DDA DA DA ADA DADD DADD ADA AA A AAAA AAAD ADD DAAA DDD ADAA ADD AA ADD DAD AAAA DDAA DDD ADDD DDD DA DDA AA AAAA ADDA AADA DD A AAAA DD DADD ADAA AAAA DADD DA DADA ADDD A ADD DAA DADA DDA DA AA ADDA DA DDAA A DADA DAAA DADD AADA DDAD DDD AAA ADAA AD A DD ADDA AA ADDD D DAAA DDD AD DDA DDD DAAD DADD DDAA ADD AAAD DADD DAAA AAA DDA DA DADD DDA DADD AADA A DADD DA DA DDA DAD DADD DDD ADDD AAA AAAD DADD DAAA AAA DAA DDD DDAD DDAA ADAA DDA AADA DADA AAAD DADD AAA D AADA DDD AAD DAD D DDAD ADA DADA DAA A DA ADA DADD D DDD DD DADA DADA AADA AAAD DADD DADA DA AD DDA AAD DAA DADA DDA DA DADA DADA DAAA DDA D DD DADD DDD AADA ADAA DADD DADA DD ADAA AAAA DADD DADA AAA DAD D DADD ADD DDAA DAA AD AD DADA AAD ADDD A AAD AAAD ADD ADDD AA DD AAA DD DDD A DDAD AAA AADA DAA AAAA AAD AADA DADD ADAA DDD DAAD AAA AAD DAA DAA AA DDA AAAA DDA AAD ADAA DAD ADD ADAA AA ADDA AAA DA AD A DD ADDA AA ADDD AD DDAD ADA DADA DAA A DDAD DDD DDAD AD ADAA AADA DD AAD ADDD ADA AAA DADD AAAA DDD AA DA ADA DDAA DDA ADA DADD DD AAD DAD D DD ADAA DDD ADAA ADD DADA AAAD AADA AADA DDD DA DAD ADD ADAA DDD AAAA DAA DAAA ADD DD DDD DAAD AADA ADD AAA DD DAA DAAA ADD D DAAA DAAA DADD AAA D AADA DDD ADDA ADD ADAA ADAA AAA DD ADD AAA DA DADD DA ADD DA DADD AADA DADD AADA D DAAA DDD AAAA ADAA AAAA DADD DD DDD ADDD AA AAD DDA DADA DAA ADAA AAAA DDD DADD AAAD D AA ADD DADD ADD D DA DADD DAAD ADD DADA DADA DA DADD DDD AAAA DADD DAA DAAA ADD ADA DADA DAA DADA DAD ADD DADA DADA DADD ADAA DDD DA DAD A ADD AD ADD DAA DADA DDA DA DADA DDA DADA DAA ADAA DAAA DDD AAD AAAD D AA AAAD AA AADA DAA AA DAAD DA DDA D AAD AAD DADD AAD AAAA AAD DAAA AD ADD DDD DDAA ADD DADA DAD DAA DADA DAAA DADD AAD D DADA DADD AAAA DDAD DDD DDD DD AAD AADA DADA AA DAAD DA AAA DADA DA ADD DADD AAA D DA ADA DADD ADD DD AAAD DAD DD DAD DADD ADD ADA AAD ADDD ADAA DADA DDD
diff --git a/2021/plaintext.5a.txt b/2021/plaintext.5a.txt
new file mode 100644 (file)
index 0000000..382498c
--- /dev/null
@@ -0,0 +1,24 @@
+jodie i can see why you are concerned but i find it hard to believe that agatha could have been part
+of a conspiracy she was a faithful colleague in all the time i worked with her and no one ever
+suggested otherwise of course we ran the usual spot checks from time to time but nothing unusual was
+found having said that the message you found in the archive is really worrying my first thought was
+that she might have been acting as a double agent trying to destabilise nazi intelligence but that
+doesnt fit with the text it is crucial to our mission that we maintain the balance of uncertainty
+and direct it to our advantage make it look like she had definitely had another agenda i trawled
+through my own records to see if anyone else agatha and i worked with might have been involved i
+hate to say it but the only person of interest at the moment is charlie we worked together on the
+kohinoor twins case and agatha washer great aunt not that treachery is a genetic trait but in
+vetting circles it can be treated like it is inherited so i suppose we ought to take that seriously
+especially since she became pretty senior in american intelligence i checked our current case files
+and although she is retired she still acts as government liaison she is in london at the moment in
+the new embassy building which will make it difficult to get hold of her if she wants to stay hidden
+we cant afford to upset our us cousins and if we are wrong about her we might also poison the well
+when it comes to intelligence exchange they havent for given us for phil by and maclean yet so i can
+imagine how they would react if it turns out that one of our own is a double agent and has
+infiltrated their inner sanctum i sent one of the elves to take a look at her apartment in new
+jersey it was pretty clean as you can imagine but they were able to lift the following extract it
+was hard to read and even harder to decipher since she used avi genere encryption but one
+incriminating feature stands out even without a decrypt she used the ad morse encoding on top of the
+vi genere cipher i am not sure what we should do next could you get the team to take a look at the
+file maybe this is all a big coincidence or a misunderstanding if not then we may have to tell
+london and washington and i am really not looking forward to that all the best harry
\ No newline at end of file
diff --git a/2021/plaintext.5b.txt b/2021/plaintext.5b.txt
new file mode 100644 (file)
index 0000000..b7acd34
--- /dev/null
@@ -0,0 +1,16 @@
+i think boss might suspect something they drafted the report on the lighthouse discovery over a
+month ago and have still not forwarded a summary to us herein the us icant risk making enquiries
+through the usual channels but i think we need to investigate i am disappointed that the trinity
+team left files in the basement when they shipped out but they did not have alot of warning and
+atleast they dont seem to have left anything current for harry to find if they had he wouldnt have
+passed the investigation to the archaeologists it would have gone straight upstairs for action i am
+in two minds about it if anyone else was investigating i would say we should ignore it they are
+unlikely to make much of a historical curiosity but if anyone could trace the link to us now then
+harry and jodie are the ones to do it jodie is a terrier who wont let anything go once she has her
+teeth into it and harry has been around long enough to know when something trivial is actually
+important on balance i think i will need to be on the ground where i can hope to influence the
+direction of their enquiries for the good of everyone we need to keep a very low profile atleast
+while the boss investigation is hot so unless the system flags a real crisis we will have to dial
+down our activities for a while we will carry on with forecasts but will not acton them unless the
+threat level rises to ten even then the curia will need to meet to decide whether it is wise to take
+action i will head to london to take charge of misdirection you can contact meat the embassy charlie
\ No newline at end of file