Done challenge 8
[cipher-tools.git] / 2018 / 2018-challenge8.ipynb
diff --git a/2018/2018-challenge8.ipynb b/2018/2018-challenge8.ipynb
new file mode 100644 (file)
index 0000000..5c69ada
--- /dev/null
@@ -0,0 +1,614 @@
+{
+ "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": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "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
+}