--- /dev/null
+{
+ "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
+}
--- /dev/null
+---
+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"
+
+```