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