{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Biolerplate" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os,sys,inspect\n", "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n", "parentdir = os.path.dirname(currentdir)\n", "sys.path.insert(0,parentdir) " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from cipher.caesar import *\n", "from cipher.affine import *\n", "from cipher.keyword_cipher import *\n", "from cipher.vigenere import *\n", "from cipher.playfair import *\n", "from cipher.column_transposition import *\n", "from support.text_prettify import *\n", "from support.plot_frequency_histogram import *" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "ca = open('8a.ciphertext').read()\n", "cb = open('8b.ciphertext').read()\n", "sca = sanitise(ca)\n", "scb = sanitise(cb)\n", "pca = letters(ca)\n", "pcb = letters(cb)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8197" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "history_words = [w.strip() for w in open('history-words.txt')]\n", "len(history_words)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "history_transpositions = collections.defaultdict(list)\n", "for word in history_words:\n", " history_transpositions[transpositions_of(word)] += [word]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Part A" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n", " \"matplotlib is currently using a non-GUI backend, \"\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fc = collections.Counter(sca)\n", "plot_frequency_histogram(fc, sort_key=fc.get)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(((0, 2, 7, 5, 6, 3, 1, 4), False, True), -8088.637383066303)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, translist=history_transpositions, fitness=Ptrigrams)\n", "(trans_a, fillcol_a, emptycol_a), score" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(((0, 2, 3, 6, 7, 4, 1, 5), False, True), -7787.854522433465)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, fitness=Ptrigrams)\n", "(trans_a, fillcol_a, emptycol_a), score" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'kedIchecdtoarounIwaseeifgwasbeinbuttchedomwtheroiniasdefmpttelyecouyandIearldnthinganythdesoutsikedoIducoindowntthespectsidunderetaeofthetobleThighpwashishlypolhagedwitulsracefothlopetthieedgengackeniprositaptheachedecocentrherlumnToviewasnmecsiblemtohanissttsuggewashatitinganythhanmoretearitappeagedtoborkrandwatttabletrehecenandofagrolrcontrushoomIpedaedpoktenndlisanoedforechthermbutanismwastherengmnothiicaechanIcolthatndTuldfickehethifthningondtetopakofhebullumthecollondidaforwroomlysafairntiubstahanalmecougismthuckhandtnthedupiwheefoldtoprethedthjoinemntecoluasaherewmetsmalltebalplagamearinmarakersartkMyheedtskipprtohedooadotheShivewArchedacarriarpsimilnsclateiwitribedradhthetofJemarknntohnTaksmhelocomaithwhturnufacsecedthesysuritythetemonnceentrakedItlooehalikehmaddalsotabethisasnleHewrniotafuaketuremherrandtdonecoulnerlybeoheheasonethadmadItmisoneparustbeocktofalnismechasthmHewaingeleadakesafemctorinViondrianLifBonandadflackheneeltthhimedforldatobuinthsafeitofehearadotheShivewArchldoitcoubecnlybeherausetsecewerehatretstoodweretenfarkevsecortheofturityhivheArclfMeitsehisaybettmyiswhakerattacallwasreranyaftethedifsotruyhadstoockwayshosoonIankuldthealthemrhoulywithintmyacIwogheadvebuldhalikeenundiselytoTancoverhannsmectthismbuughatthondetremiassdmeIwulntillvedoerablheswnintsIdhadowhinidnttewaktherneesanyoounlsearcoudbutIesuldntbInereandackededbilnupUntrehowtheeenadntbhtoenougrrygetHavedinvolsadinthireIventuwasstilltaintcerhewnthatealouldbtohlowedtaselpoutreIwasnureallysatithatnecuonalsasiritywedbnvolvsabutIwaelysolutinhcertadwaewouleetnttoseedhisInetoedtogelyutsafmebandcothaackwioweteamsprocouldexpperlyheAloreteanrchivoutdfindheTwhattfesannsaBeftoredeftoreIloneItookookmoreldgaarounngttheripaphefewatwersthftaereletinndputodegthececubooksntorelyietoapockckpfmybatilackIsdntlcoulvetbelieatthatmyshaackeritbdleftbutehindpstperhasseheymitheditinintgloomxciheirettotemenrthgathernmegoveperentpahthswhicfoueyhadothndIfnsecingeltofameouwasthisIintcertaecohatthkwadeboohreswortIhaadingdtidnthanspmetoiproectitbutperlyctitheseheVonontrecigenelooiphersolkedabfasutelyingcinat'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "column_transposition_decipher(pca, trans_a, fillcolumnwise=fillcol_a, emptycolumnwise=emptycol_a)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "262.0" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(pca) / 8" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'kdIecceh'" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "first_row = every_nth(pca, 262)[0]\n", "first_row" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('kdIecceh', 'kdIecceh')" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "target_pt = 'Ichecked'\n", "# tta = (2, 1, 0, 3, 4, 5, 6, 7)\n", "tta = (5, 7, 0, 3, 4, 1, 6, 2)\n", "tta = (5, 7, 0, 6, 4, 1, 3, 2)\n", "tta = (5, 7, 0, 3, 1, 4, 6, 2)\n", "tta = (5, 7, 0, 6, 1, 4, 3, 2)\n", "\n", "column_transposition_encipher(target_pt, tta), first_row" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "sample_ta = [(5, 7, 0, 3, 4, 1, 6, 2), (5, 7, 0, 6, 4, 1, 3, 2), (5, 7, 0, 3, 1, 4, 6, 2), (5, 7, 0, 6, 1, 4, 3, 2)]" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(((5, 7, 0, 3, 4, 1, 6, 2), False, True), -7097.955599556401)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, translist=sample_ta, fitness=Ptrigrams)\n", "(trans_a, fillcol_a, emptycol_a), score" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'IcheckedaroundtoseeifIwasbeingwatchedbuttheroomwasdefinitelyemptyandIcouldnthearanythingoutsidesoIduckeddowntoinspecttheundersideofthetableThetopwashighlypolishedwithagracefulslopetotheedgethickeningasitapproachedthecentrecolumnTherewasnovisiblemechanismtosuggestthatitwasanythingmorethanitappearedtobeagrandworktableatthecentreofagrandcontrolroomIpushedpokedandlistenedforanothermechanismbuttherewasnothingmechanicalthatIcouldfindThethickeningofthetopandthebulkofthecolumndidallowroomforafairlysubstantialmechanismthoughandtuckedupinthefoldwherethetopjoinedthecolumntherewasasmallmetalplatebearingamakersmarkMyheartskippedthedoortotheShadowArchivecarriedasimilarplateinscribedwiththetrademarkofJohnTannthelocksmithwhomanufacturedthesecuritysystemontheentranceItlookedlikehehadalsomadethistableHewasnotafurnituremakerandtherecouldonlybeonereasonhehadmadethisoneItmustbepartofalockmechanismHewastheleadingsafemakerinVictorianLondonandifBlackhadfelttheneedforhimtobuildasafeintheheartoftheShadowArchiveitcouldonlybebecausethereweresecretsthatweretoodarkevenforthesecurityoftheArchiveitselfMaybethisiswhatmyattackerwasreallyafterandifsotheyhadstruckwaytoosoonIshouldthankthemreallywithoutmyachingheadIwouldhavebeenunlikelytodiscoverTannsmechanismbutthatthoughtremindedmeIwasstillvulnerabledownintheshadowsIdidntthinktherewasanyoneelsearoundbutIcouldntbesureandIneededbackupUntilnowtherehadntbeenenoughtogetHarryinvolvedinthisadventureIstillwasntcertainthathewouldbeallowedtohelpoutasIwasntreallysurethatnationalsecuritywasinvolvedbutIwasabsolutelycertainhewouldwanttoseethisIneededtogetoutsafelyandcomebackwithateamsowecouldproperlyexploretheArchiveandfindoutwhattheTannsafestoredBeforeIleftItookonemorelookaroundgatheringthefewpapersthatwereleftandputtingthecodebooksecurelyintoapocketofmybackpackIstillcouldntbelievethatmyattackershadleftitbehindbutperhapstheymisseditinthegloomintheirexcitementtogatherthegovernmentpaperswhichtheyhadfoundIfnothingelsecameoutofthisIwascertainthatthecodebookwasworthreadingIhadnthadtimetoinspectitproperlybutthesectionontheVigenerecipherlookedabsolutelyfascinating'" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "raw_pta = column_transposition_decipher(pca, trans_a, fillcolumnwise=fillcol_a, emptycolumnwise=emptycol_a)\n", "raw_pta" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I checked around to see if I was being watched but the room was definitely empty and I couldnt hear\n", "anything outside so I ducked down to inspect the underside of the table The top was highly polished\n", "with a graceful slope to the edge thickening as it approached the centre column There was no visible\n", "mechanism to suggest that it was anything more than it appeared to be a grand work table at the\n", "centre of a grand control room I pushed poked and listened for another mechanism but there was\n", "nothing mechanical that I could find The thickening of the top and the bulk of the column did allow\n", "room for a fairly substantial mechanism though and tucked up in the fold where the top joined the\n", "column there was a small metal plate bearing a makers mark My heart skipped the door to the Shadow\n", "Archive carried a similar plate inscribed with the trademark of John Tann the locksmith who\n", "manufactured the security system on the entrance It looked like he had also made this table He was\n", "not a furniture maker and there could only be one reason he had made this one It must be part of a\n", "lock mechanism He was the leading safe maker in Victorian London and if Black had felt the need for\n", "him to build a safe in the heart of the Shadow Archive it could only be because there were secrets\n", "that were too dark even for the security of the Archive itself Maybe this is what my attacker was\n", "really after and if so they had struck way too soon I should thank them really without my aching\n", "head I would have been unlikely to discover Tan ns mechanism but that thought reminded me I was\n", "still vulnerable down in the shadows I didnt think there was anyone else around but I couldnt be\n", "sure and I needed backup Until now there hadnt been enough to get Harry involved in this adventure I\n", "still wasnt certain that he would be allowed to help out as I wasnt really sure that national\n", "security was involved but I was absolutely certain he would want to see this I needed to get out\n", "safely and comeback with a team so we could properly explore the Archive and find out what the Tann\n", "safe stored Before I left I took one more look around gathering the few papers that were left and\n", "putting the codebook securely into a pocket of my backpack I still couldnt believe that my attackers\n", "had left it behind but perhaps they missed it in the gloom in their excitement to gather the\n", "government papers which they had found If nothing else came out of this I was certain that the\n", "codebook was worth reading I hadnt had time to inspect it properly but the section on the Vi genere\n", "cipher looked absolutely fascinating\n" ] } ], "source": [ "print(lcat(tpack(segment(raw_pta))))" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transpositions[trans_a]" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "history_transpositions[trans_a]" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[], [], ['enumerated'], []]" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[transpositions[tr] for tr in sample_ta]" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2581" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "open('8a.plaintext', 'w').write(lcat(tpack(segment(raw_pta))))" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "279585" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "many_words = [w.strip() for w in open('../many_word_lists/combined.txt')]\n", "len(many_words)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [], "source": [ "many_transpositions = collections.defaultdict(list)\n", "for word in many_words:\n", " many_transpositions[transpositions_of(word)] += [word]" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['gothicise', 'gothicises']" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "many_transpositions[trans_a]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Part B" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'shadow'" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "key_b, score = vigenere_frequency_break(scb)\n", "key_b" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'elliothasdonehimselfnofavoursinarguingthepragmaticlineattheconstantinopleconferencedisraelicaughtthemoodwithhispamphletandthepeopledonotseemtoagreethatbulgarianlivescountforlessinthecalculusofinternationalaffairsithinksalisburyplanstomovehimonperhapsbacktoviennahewassuccessfulthereitismostunusualtohaveannoyedbothsalisburyandgladstonebutihavesomesympathywithhisviewstheterribleeventsthathaveprecipitatedthiscrisiscannotbeundoneandthereareotherconsiderationsrussianaggressionmuststillbeimpededifwearetoretainourinfluenceintheregionmyagentstellmethattherussianemperormetwiththeaustriansatbudapestatthestartoftheyeartodiscusstheirintentionsintheeventofwaranditisrumouredthattheyplantorestructurethebalkansinanefforttocontroltheslavicmovesforaunifiedstateitismyownviewthattheslavsmaybeamostusefulallyinblockingtheexpansionistmovementinrussiaandihaveadvisedthegovernmenttoinvitetheaustrianstojoinusinmarchtoseeifwecaneffectadiplomaticsolutiontountanglethisgordianknotperhapswecanfindsomethingmoreattractiveforthemthatwillweakentheirdependenceontsaralexanderiiifwefailthenifearthatmoredirectactionmayneedtobetakenihaveinmypossessioncopiesofcertainlettersthathavebeencirculatinginfranzjosefscourtthatithinkmightbesufficientlyembarrassingtoconcentratemindsontheadvantagesofworkingwithusinstabilityintheregioniscertainlysomethingtobefearedbutperhapswecanconvincetheaustriansthatstabilitywouldbeworseifitissecuredbytherussiansifwecannotturnaustriatoourcauseitmightbenecessarytoundertakeacampaigntostirupthelocalpopulationsperhapsrussiawouldthinktwicebeforegettinginvolvediftheywerenotabletosecureastablesettlementbyforceofarmsalonethelessonsofthecrimeahavenotbeenforgottenbyanyofitscombatantsmodernwarfareisgrowingindustrialinitsscaleandthecostsofconflictareprohibitiveiamcertainthatthestoriestoldbynightingaleofthehorrificwoundssufferedtherehavesoftenedtheappetiteofsomeforopenconflictandperhapsthatisresponsibleforhermajestyssupportoftheshadowarchiveandallitsworksimustnotletherdownnortheempire'" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vigenere_decipher(scb, key_b)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "elliot has done himself no favours in arguing the pragmatic line at the constantinople conference\n", "disraeli caught the mood with his pamphlet and the people do not seem to agree that bulgarian lives\n", "count for less in the calculus of international affairs i think salisbury plans to move him on\n", "perhaps back to vienna he was successful there it is most unusual to have annoyed both salisbury and\n", "gladstone but i have some sympathy with his views the terrible events that have precipitated this\n", "crisis can not be undone and there are other considerations russian aggression must still be impeded\n", "if we are to retain our influence in the region my agents tell me that the russian emperor met with\n", "the austrians at budapest at the start of the year to discuss their intentions in the event of war\n", "and it is rumoured that they plan to restructure the balkans in an effort to control the slavic\n", "moves for a unified state it is my own view that the slavs maybe a most useful ally in blocking the\n", "expansionist movement in russia and i have advised the government to invite the austrians to join us\n", "in march to see if we can effect a diplomatic solution to untangle this gordian knot perhaps we can\n", "find something more attractive for them that will weaken their dependence on tsar alexander ii if we\n", "fail then i fear that more direct action may need to be taken i have in my possession copies of\n", "certain letters that have been circulating in franz josef s court that i think might be sufficiently\n", "embarrassing to concentrate minds on the advantages of working with us instability in the region is\n", "certainly something to be feared but perhaps we can convince the austrians that stability would be\n", "worse if it is secured by the russians if we can not turn austria to our cause it might be necessary\n", "to undertake a campaign to stir up the local populations perhaps russia would think twice before\n", "getting involved if they were notable to secure as table settlement by force of arms alone the\n", "lessons of the crime a have not been forgotten by any of its combatants modern warfare is growing\n", "industrial in its scale and the costs of conflict are prohibitive i am certain that the stories told\n", "by nightingale of the horrific wounds suffered there have softened the appetite of some for open\n", "conflict and perhaps that is responsible for her majestys support of the shadow archive and all its\n", "works i must not let her down nor the empire\n" ] } ], "source": [ "print(lcat(tpack(segment(vigenere_decipher(scb, key_b)))))" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2419" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "open('8b.plaintext', 'w').write(lcat(tpack(segment(vigenere_decipher(scb, key_b)))))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.7" } }, "nbformat": 4, "nbformat_minor": 2 }