Done 2018 challenge 10
[cipher-tools.git] / 2018 / 2018-challenge9.ipynb
diff --git a/2018/2018-challenge9.ipynb b/2018/2018-challenge9.ipynb
new file mode 100644 (file)
index 0000000..ebf6dd6
--- /dev/null
@@ -0,0 +1,374 @@
+{
+ "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": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('9a.ciphertext').read()\n",
+    "cb = open('9b.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": 6,
+   "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": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": [
+    "fc = collections.Counter(sca)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dynamite'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(sca)\n",
+    "key_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'theengineersharrybroughtwithhimwantedtotakesawsandtorchestothetablesafebutneitherofuswerekeenicouldseethatitwouldbeworthalottocollectorsandprobablybelongedinamuseumharrysaidheagreedbutihadafeelinghewanteditinstalledbackinheadquarterstherewassomethingproprietorialinthewayhelookedatitittookthetwoofuseighteenhourstocrackitbutwithasquadronofspecialforcesfromherefordguardingustherewasnoriskthatmyattackerswouldreturniaskedharryhowhegotauthorisationtobringtheminafterallwestillwerentsurethattherewereanynationalsecurityimplicationsbuthejustlaughedandpointedoutthatwewerecurrentlysomewhereundernewscotlandyardandithadnttakenmuchtoconvincethehomesecretarythatweneededapropersecurityteamtoguardtheshadowarchiveanotherteamofanalystshadcampedononesideofthecommandcentreandwerecombingthroughblackscodebookandthefewpapersthatourantagonistshadleftbehindfromtimetotimeoneofthetrooperswouldarrivewithanotherboxofdocumentsretrievedfromasideroomoramoredistantpartofthearchivelabyrinthmostcouldbedecryptedquicklyusingthestandardtoolsblackhadusedarangeofciphersincludingsubstitutionandtranspositionandalmostnoneofitwasharderthanavigenereitwasslowsincethepapershadtobehandledwithcareandthescannertheyhadbroughtwiththemwasntreallydesignedforthissortofworkacoupleoftimestheycalledharryovertoshowhimsomethingandhereaditnoddedthencamebacktoworkonthesafeasweworkedwetalkedaboutwhatihadlearnedconcerningtheshadowarchiveandblackssecretworkforthegovernmentharrydidntgivemuchawaybutihadafeelinghehadheardsomeofthisstorybeforeandafterthesecondtimehewascalledawayheseemedparticularlythoughtfuliaskedhimwhatwasbotheringhimbuthewasenjoyingbeingcryptichesaidsomethingaboutthebalkanproblemthenmutteredsteveturnerspoemhistorylessonhistoryrepeatsitselfhastonoonelistensicouldntgetanythingmoreoutofhimexceptsomecommentaboutworkingbackwardsthroughthepaperssoiturnedmyattentionbacktothesafethemechanismwasbiggerandheavierthanwewereusedtoandhadbeenexquisitelymadethecomponentsslidalmostnoiselesslyoveroneanotherandtheloudclicksihadheardwhenmovingthetableseemedtobetheresultofabrokencogtoothcatchingonthebarrelsthatmadeitevenhardertoopenwhatlittlenoisethelocktumblersmadewasheavilydisguisedandwehadtoresorttodrillingasmallaccessholetopassanendoscopeintotheinterioritwasaswellwehadtakentheeffortsittinginthemiddleofapileofnotebooksandpaperswasasmallpileofwhatlookedlikeexplosivesthesafewasriggedtoblowifwemadeamistake'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(sca, key_a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the engineers harry brought with him wanted to take saws and torches to the table safe but neither\n",
+      "of us were keen i could see that it would be worth alot to collectors and probably belonged in a\n",
+      "museum harry said he agreed but i had a feeling he wanted it installed back in headquarters there\n",
+      "was something proprietor i al in the way he looked at it it took the two of us eighteen hours to\n",
+      "crack it but with a squadron of special forces from hereford guarding us there was no risk that my\n",
+      "attackers would return i asked harry how he got authorisation to bring them in after all we still\n",
+      "werent sure that there were any national security implications but he just laughed and pointed out\n",
+      "that we were currently somewhere under new scotland yard and it hadnt taken much to convince the\n",
+      "home secretary that we needed a proper security team to guard the shadow archive another team of\n",
+      "analysts had camped on one side of the command centre and were combing through blacks codebook and\n",
+      "the few papers that our antagonists had left behind from time to time one of the troopers would\n",
+      "arrive with another box of documents retrieved from aside room or a more distant part of the archive\n",
+      "labyrinth most could be decrypted quickly using the standard tools black had used a range of ciphers\n",
+      "including substitution and transposition and almost none of it was harder than avi genere it was\n",
+      "slow since the papers had to be handled with care and the scanner they had brought with them wasnt\n",
+      "really designed for this sort of work a couple of times they called harry over to show him something\n",
+      "and he read it nodded then came back to work on the safe as we worked we talked about what i had\n",
+      "learned concerning the shadow archive and blacks secret work for the government harry didnt give\n",
+      "much away but i had a feeling he had heard some of this story before and after the second time he\n",
+      "was called away he seemed particularly thoughtful i asked him what was bothering him but he was\n",
+      "enjoying being cryptic he said something about the balkan problem then muttered steve turners poem\n",
+      "history lesson history repeats itself has to no one listens i couldnt get anything more out of him\n",
+      "except some comment about working backwards through the papers so i turned my attention back to the\n",
+      "safe the mechanism was bigger and heavier than we were used to and had been exquisitely made the\n",
+      "components slid almost noiselessly over one another and the loud clicks i had heard when moving the\n",
+      "table seemed to be the result of a broken cog tooth catching on the barrels that made it even harder\n",
+      "to open what little noise the lock tumblers made was heavily disguised and we had to resort to\n",
+      "drilling a small access hole to pass an endoscope into the interior it was as well we had taken the\n",
+      "effort sitting in the middle of a pile of notebooks and papers was a small pile of what looked like\n",
+      "explosives the safe was rigged to blow if we made a mistake\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(sca, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2913"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('9a.plaintext', 'w').write(prettify(vigenere_decipher(sca, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part B"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'turkey'"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(scb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'erutuferuceseromdnawenagnitaercfoepohehtnimehthtiwylesolckrowoteunitnoclliwinoigertahtnidlohtoofasueviglliwainsobnikrowtentnegaruoosfiyltnenamrepnoitseuqnaklabehtelttesotspahrepdnasniaglairotirretnaissurenimrednuotepohewetatsnamottoehtotkcabainodecamgnidartybemitemasehttasetuoredartnaenarretidemehtfolortnocruognitnemecsurpycniagyamewtahtsruomurdraehevahidnaseitinutroppognidartnihcireblliwynamregniraazabcitamolpidehtfoerehpsomtadeiznerfehtesruocfosrewoprojamehtnomehthguorhtraeboterusserpgnirbnacewtahtepohehtniytilibatsniderutrunevahsnaklabehtssorcastnegaymseitrapdnasetatsrellamsehtnosisucofymtubweivaevaherusmailliwsrewoprojamehtfollassergnocehtfonrecnocelpicnirpehtsideveihcaebthgimnoitacifinusihtrehtehwdnawohfonoitseuqehtelbitapmocnieraesehtdnasweivlavirynamyreveraerehttahtrehtartubaediraelcakcalyehttahttonsitignidaelsimsitahtspahrepnoitacifinuehtdaeldluohsytraphcihwfoaediraelcondnanworiehtfosnoitibmalacitilopdnalarutlucdeiravhtiwdedividniamersevlesmehtsetatsnaklabehtnoitulosnaklabakeesohwesohtdnaaissurnihtiweildluohsrewopstifosucolehttahteveilebohwesohtneewtebtilpsylpeedsitubdeifinuneebevahylatidnaynamregtahtyawemasehtnisetatscivalsehtetinuotsmiatnemevomcivalsnapehtsisircehtfotuoyawaeesyameweveilebinehtnilrebtaadnegaehtlortnocnacewfitcilfnocrehtrufmorfesoloteromgnihtemosevahyehttahtdesilaerevahlladnatnenitnocehtssorcatpureyamrawtahttaerhtgnirehtagehteesotnugebevahsrewoprojamehtfollasevilnitsocrewolhcumatadeeccusthgimycamolpidfosdohtemwenruotahtsiepohymtsoctaergtanetfodnathguoberagninniwhtrowseirotcivllatahtweivymsititubthguorbnaemylerustsumitahtdiasdnaemdetcerrocehriafyalpotsihtdiasinehwnoituloserarofepohotnigebnacinilrebnissergnocgnidnepmiehttathguobebthgimecaeptahttcepsorpehthtiwyllanifwonnihtiwseimenegnithgifygreneelbaredisnocdednepxeevahidnallahetihwniralupopyllasrevinuneebtonevahsdohtemymsselehtenonmelborphsikrutehtotnoitulosnworuotneserpotsrewopgnidaelrehtohtiwetaitogenotnigebotelbaerewewdnocesdnaseimeneruofosecivrescitamolpidehtnihtiwkrowtentnegaruopolevedotelbaerewewtsrifsgnihtowtdeveihcayaledsihttahtflesymtrofmocidnaelbativeniehtyaledotdekrowseillaehtgnomanoisufnocgniwosfoygetartsruonoituloslanoitanretninaotelbanemaebotgniraeppaelihwnoitisophsitirbehtgnisilanigramylevitceffednaairtsuadnaynamregniseillarehhtiwnoitcaroftroppusgnidliubyltcefrepdnahrehdeyalpsahaissurderaefewtahtllaneebsahrawhsikrutossureht'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb1 = vigenere_decipher(scb, key_b)\n",
+    "pb1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the russo turkish war has been all that we feared russia has played her hand perfectly building\n",
+      "support for action with her allies in germany and austria and effectively marginalising the british\n",
+      "position while appearing to be amenable to an international solution our strategy of sowing\n",
+      "confusion among the allies worked to delay the inevitable and i comfort myself that this delay\n",
+      "achieved two things first we were able to develop our agent network within the diplomatic services\n",
+      "of our enemies and second we were able to begin to negotiate with other leading powers to present\n",
+      "our own solution to the turkish problem nonetheless my methods have not been universally popular in\n",
+      "whitehall and i have expended considerable energy fighting enemies within now finally with the\n",
+      "prospect that peace might be bought at the impending congress in berlin i can begin to hope for a\n",
+      "resolution when i said this to playfair he corrected me and said that i must surely mean brought but\n",
+      "it is my view that all victories worth winning are bought and often at great cost my hope is that\n",
+      "our new methods of diplomacy might succeed at a much lower cost in lives all of the major powers\n",
+      "have begun to see the gathering threat that war may erupt across the continent and all have realised\n",
+      "that they have something more to lose from further conflict if we can control the agenda at berlin\n",
+      "then i believe we may see away out of the crisis the pan slavic movement aims to unite the slavic\n",
+      "states in the same way that germany and italy have been unified but is deeply split between those\n",
+      "who believe that the locus of its power should lie within russia and those who seek a balkan\n",
+      "solution the balkan states themselves remain divided with varied cultural and political ambitions of\n",
+      "their own and no clear idea of which party should lead the unification perhaps that is misleading it\n",
+      "is not that they lack a clear idea but rather that there are very many rival views and these are\n",
+      "incompatible the question of how and whether this unification might be achieved is the principle\n",
+      "concern of the congress all of the major powers william sure have a view but my focus is on the\n",
+      "smaller states and parties my agents across the balkans have nurtured instability in the hope that\n",
+      "we can bring pressure to bear through the mon the major powers of course the frenzied atmosphere of\n",
+      "the diplomatic bazaar in germany will be rich in trading opportunities and i have heard rumours that\n",
+      "we may gain cyprus cementing our control of the mediterranean trade routes at the same time by\n",
+      "trading macedonia back to the ottoman state we hope to undermine russian territorial gains and\n",
+      "perhaps to settle the balkan question permanently if so our agent network in bosnia will give usa\n",
+      "foothold in that region i will continue to work closely with them in the hope of creating a new and\n",
+      "more secure future\n"
+     ]
+    }
+   ],
+   "source": [
+    "rpb1 = cat(reversed(pb1))\n",
+    "print(prettify(rpb1))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2856"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('9b.plaintext', 'w').write(prettify(rpb1))"
+   ]
+  },
+  {
+   "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
+}