--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "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.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": 3,
+ "id": "d9dd1b5e",
+ "metadata": {
+ "Collapsed": "false"
+ },
+ "outputs": [],
+ "source": [
+ "challenge_number = 6\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": 20,
+ "id": "0f1f792a",
+ "metadata": {
+ "Collapsed": "false"
+ },
+ "outputs": [],
+ "source": [
+ "ca = open(ciphertext_a_filename).read()\n",
+ "cb = open(ciphertext_b_filename).read()\n",
+ "\n",
+ "sca = sanitise(ca)\n",
+ "rsca = cat(reversed(sca))\n",
+ "scb = sanitise(cb)\n",
+ "rscb = cat(reversed(scb))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "b8d5f9ec-27f1-498b-8e64-c5eb2424e581",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Counter({'r': 124,\n",
+ " 'm': 42,\n",
+ " 't': 227,\n",
+ " 'u': 65,\n",
+ " 'v': 24,\n",
+ " 'a': 163,\n",
+ " 's': 138,\n",
+ " 'w': 41,\n",
+ " 'c': 59,\n",
+ " 'i': 158,\n",
+ " 'f': 35,\n",
+ " 'd': 66,\n",
+ " 'e': 279,\n",
+ " 'l': 44,\n",
+ " 'j': 2,\n",
+ " 'h': 142,\n",
+ " 'o': 130,\n",
+ " 'n': 144,\n",
+ " 'b': 36,\n",
+ " 'g': 63,\n",
+ " 'y': 37,\n",
+ " 'p': 29,\n",
+ " 'k': 12,\n",
+ " 'q': 3,\n",
+ " 'x': 2})"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "sca_counts = collections.Counter(sca)\n",
+ "sca_counts"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "b5cabba1-ac75-46ea-ac05-8699cc88d986",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<AxesSubplot:>"
+ ]
+ },
+ "execution_count": 6,
+ "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": "61ce2102-294e-4b1a-842c-1607aa7a4b05",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6 \n",
+ "\n",
+ "rnhsheesramriuewtasdtitnaceiglucseeeocervciainrorfaerbtlishirbsaenshatsasituehetwetsqniofncastwohaswiigndhfthraeraettotefrhthmithgdsrtayuackerwdhrahetlnitmsofmoasuoaurgeeugeeoovesrjulithtetrmattrehearihsinonecmhepuaownietserwysrcafntghhhecseiytuefesllcahonrsbeebgaatesethshtecaabbogweboantimdcurseoitiafsderinmoamndnaemhsiscasbveeosatrinhitwnlfsrucennhdedeeloebetnpbohethfefdarcenggnieeedintscutecsoshmrardyoloertoeaeoubnhsitmierhutetlhrdinstohaautahywsenetnsrgecnciethnpieneetntesetnhrugiysnhwviahwcataerfbttuedfihlfenrhegncbithehmgiiihembsehtomacoascdiiteetccuhghapharoimapsrdiastoonomhicaotindfthreaekeeourocanitoeisseudlhisthyttehatvtitirpentohateenesydblubnrceeyedteignudageihrweniiashsodneevysrrpelittstieetniviitnicuabmshatohertfwofedoarfiwleiouggieethtltehanyflettnoeawtmamhbtiseinoaniggevthnrwaeasrowneynitbgavondarowingiisipsacnbonhueytsdtnclgihnhouhicnosesraiuristitnkitsohwnuchdogoeaguwnomootpdcsslrhvaoeeitwneudcipatohnpsriotiiicpionhisregseuetudoshseocaneettmixreouhfyuogecldunyosttmhitneslnoekeifoylaobssueaerqejiedhyrhaeaisuyihreemssthrebenhyrdioyfosauikhhtnottahaswerlrsagooirodnnebutactwntnetictthnoldohduuroegenhevtgetneceneonsotheettrlereasiketwgewavisaetuusesmishetvnlvimoedohewarrondsokthosaatfsiavkasinrdihatratceildogatesotcaltyalyanathehtinttarothtveetaheiemisgbmrorleftrgithnceoubnopinoyraocfuruehseesinetirxppneedstnagsoshaghgtmvbtdevrelietabundetsteorebotfechttreytinergupttianmpsssmteibwahthoreeamcinsnaeweorladievyietsgaitgtieehonfarsptycnduahermctdeteenafevyttighihtneeitlmaskasonilnashglytefditertmeniearigwetiwvicttatuubwahttatyesragtseqrituegnofwnehhyodydnlratseteeinllnttgincthtewesuntraehertnmereiitttdtrrabacikchrtahousaghaeocsrudrosgtfeeieheiatysatihgtnggosasetheehateimhtebehateeadtelouegantnihnopgnenaentioidthrelefharsetaldaebgtiacinoldewowgnthnisthaatearhcdvgnietrsgmmtfaaroethettiriiairuaiwnishthekamgehtneahhesutnuerekessanithrybebsolstnhsonnwentdehoneurantepdpgsrepddeoryhttswsahetpassdreenmnohepnatitcisyconoutswenibrevhaodetuddaoesthparatregyahyasaeotisnaeapgarcoagnrdlotherrorepstedvtoidierppuofeauorerntrfooeemohwsnt\n"
+ ]
+ }
+ ],
+ "source": [
+ "key_a, score_a = railfence_break(sca, fitness=Ptrigrams)\n",
+ "print(key_a, '\\n')\n",
+ "pa = railfence_decipher(sca, key_a)\n",
+ "print(pa)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "id": "605792ee-8bbf-44da-b33f-6bd2321f449e",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(2, 4, 3, 0, 1) False True \n",
+ "\n",
+ "harryiamsurethismustbeveryhardforyouasiknowthatcharliewasagoodfriendbutwecantletthatcloudourjudgementgiventhecontentofherletterlastweekwehavetoassumesheisinvolvedsomehowandworkonthatbasishavingsaidthatcharliedoesntactuallysayanythingthatprovesthatsheisamemberofthelighthouseconspiracyofcoursesheisanexperiencedagentsothatmightbedeliberatebutshedoesrefertothetrinitygroupanditspossiblethattheamericanswerealreadyinvestigatingtheconspiracyunderthatcodenameeverythingintheemailtakesonaslightlydifferentmeaningifweviewitthatwaybutthatraisesthequestionofwhytheydidntsharetheintelligencewithusinthemeantimeitriedtotrackbackthroughagathasrecordtoseeifthereisanythingtosuggestthatshemighthavebeenadoubleagentnothingmentionedinthefileraisedaflagbutinoticedtwothingsintheattachedvettingsummaryafterherinitialruninwiththegermantreasurehuntersseekingthebabylonstoneshewentontherunandpapersreportedthatshewasapassengeronthetitanicasyouknowsheneverboardedandusedthattragedyasawaytodisappearaccordingtothereportshedidnotreappearforoverfourteenmonthswhenshewasrecruitedasanintelligencesourceincairoforthebritishembassythatraisesthequestionofwhatshewasdoingfortheyeartheotherthingthatstruckachordwasthementionofmassouriegeorgeeverestbuiltaretreatthereandhisnamecameupwheniwasresearchingthesecurityfilesofcharlesbabbageitseemsthatbabbagewasintroducedtoideasfromindianmathematicsbyeverestandthisinfluencedthedevelopmentofthedifferenceengineanditssuccessorsmaryboolewroteaboutthisinherletterindianthoughtandwesternscienceinthenineteenthcenturygivenwhatchwroteaboutthedifferenceenginethismightbemorethanacoincidencethoughperhapsiamreadingtoomuchintoitforthesakeofourtraineesishouldsaythatthevettingreporthasbeendoubleencryptedusingavigenerewithasecondverysimpletwistimentionitbecausethatthrewmeoffforawhileisuggestthattheyreflectonwhatmightbegoingongiventhatwearenowtryingtoavoidraisingsuspicionbytheusandthelighthouseconspiratorsithinkweshouldchangeourownprotocolssoihaveswitcheduptoatranspositioncipherisuggestyoudothesamenexttimethoughyoucouldtrysomethingelselikeapolybiussquarejodie\n"
+ ]
+ }
+ ],
+ "source": [
+ "(word_a, fill_a, empty_a), score_a = column_transposition_break(sca, fitness=Ptrigrams)\n",
+ "print(word_a, fill_a, empty_a, '\\n')\n",
+ "pa = column_transposition_decipher(sca, word_a, fillcolumnwise=fill_a, emptycolumnwise=empty_a)\n",
+ "print(pa)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "b66bf02f-9e8b-421d-8549-ab00774465ce",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(2, 4, 3, 0, 1)"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "transpositions_of('deacb')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "b9fa44e0-fd0c-4ff3-b62b-81db5c4b6109",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['gibed',\n",
+ " 'gybed',\n",
+ " 'hodge',\n",
+ " 'image',\n",
+ " 'imbed',\n",
+ " 'jodie',\n",
+ " 'judge',\n",
+ " 'lobed',\n",
+ " 'locke',\n",
+ " 'lodge',\n",
+ " 'lubed',\n",
+ " 'lucid',\n",
+ " 'noble',\n",
+ " 'noemi',\n",
+ " 'nudge',\n",
+ " 'osage',\n",
+ " 'prank',\n",
+ " 'pubic',\n",
+ " 'pylon',\n",
+ " 'quake',\n",
+ " 'ruble',\n",
+ " 'stage',\n",
+ " 'staid',\n",
+ " 'stake',\n",
+ " 'stale',\n",
+ " 'stalk',\n",
+ " 'stand',\n",
+ " 'stank',\n",
+ " 'staph',\n",
+ " 'stare',\n",
+ " 'stark',\n",
+ " 'stern',\n",
+ " 'stink',\n",
+ " 'sucre',\n",
+ " 'swage',\n",
+ " 'swami',\n",
+ " 'swank',\n",
+ " 'sward',\n",
+ " 'swarm',\n",
+ " 'swirl',\n",
+ " 'tubed',\n",
+ " 'twang',\n",
+ " 'twerp',\n",
+ " 'twirl',\n",
+ " 'wyeth',\n",
+ " 'fibbed',\n",
+ " 'fobbed',\n",
+ " 'gobbed',\n",
+ " 'jobbed',\n",
+ " 'judged',\n",
+ " 'lobbed',\n",
+ " 'lodged',\n",
+ " 'lucile',\n",
+ " 'lychee',\n",
+ " 'mobbed',\n",
+ " 'muddle',\n",
+ " 'mumble',\n",
+ " 'noodle',\n",
+ " 'nudged',\n",
+ " 'osages',\n",
+ " 'puddle',\n",
+ " 'ruanda',\n",
+ " 'rubbed',\n",
+ " 'rubble',\n",
+ " 'rubier',\n",
+ " 'rubric',\n",
+ " 'rwanda',\n",
+ " 'stages',\n",
+ " 'stakes',\n",
+ " 'stales',\n",
+ " 'stalks',\n",
+ " 'stands',\n",
+ " 'staphs',\n",
+ " 'starer',\n",
+ " 'stares',\n",
+ " 'stated',\n",
+ " 'static',\n",
+ " 'stereo',\n",
+ " 'sterne',\n",
+ " 'sterns',\n",
+ " 'stinks',\n",
+ " 'subbed',\n",
+ " 'sudoku',\n",
+ " 'summon',\n",
+ " 'swamis',\n",
+ " 'swanee',\n",
+ " 'swanks',\n",
+ " 'swards',\n",
+ " 'swarms',\n",
+ " 'swirls',\n",
+ " 'sydney',\n",
+ " 'tubule',\n",
+ " 'tycoon',\n",
+ " 'imbibed',\n",
+ " 'inching',\n",
+ " 'kneeing',\n",
+ " 'lucille',\n",
+ " 'muddied',\n",
+ " 'muddled',\n",
+ " 'nodding',\n",
+ " 'noodled',\n",
+ " 'prairie',\n",
+ " 'premier',\n",
+ " 'puddled',\n",
+ " 'quahaug',\n",
+ " 'ruddier',\n",
+ " 'rwandan',\n",
+ " 'stalest',\n",
+ " 'starter',\n",
+ " 'stashes',\n",
+ " 'statics',\n",
+ " 'steepen',\n",
+ " 'steeple',\n",
+ " 'stereos',\n",
+ " 'sterner',\n",
+ " 'sternes',\n",
+ " 'stetson',\n",
+ " 'subsume',\n",
+ " 'succeed',\n",
+ " 'sudokus',\n",
+ " 'summons',\n",
+ " 'susanne',\n",
+ " 'swansea',\n",
+ " 'swashes',\n",
+ " 'sydneys',\n",
+ " 'tuition',\n",
+ " 'imbedded',\n",
+ " 'indigene',\n",
+ " 'premiere',\n",
+ " 'starters',\n",
+ " 'steeples',\n",
+ " 'sternest',\n",
+ " 'stetsons',\n",
+ " 'subsumes',\n",
+ " 'succeeds',\n",
+ " 'summonss',\n",
+ " 'susannes',\n",
+ " 'swanseas',\n",
+ " 'statistic',\n",
+ " 'steeliest',\n",
+ " 'steepness',\n",
+ " 'sternness',\n",
+ " 'succeeded',\n",
+ " 'statistics',\n",
+ " 'steepnesss',\n",
+ " 'sternnesss',\n",
+ " 'ouagadougou']"
+ ]
+ },
+ "execution_count": 29,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "transpositions[word_a]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "id": "c7f2e770-8062-4d18-b90a-cb2e410ef88c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "harry i am sure this must be very hard for you as i know that charlie was a good friend but we cant\n",
+ "let that cloud our judgement given the content of her letter last week we have to assumes he is\n",
+ "involved somehow and work on that basis having said that charlie doesnt actually say anything that\n",
+ "proves that she is a member of the lighthouse conspiracy of course she is an experienced agent so\n",
+ "that might be deliberate but she does refer to the trinity group and its possible that the americans\n",
+ "were already investigating the conspiracy under that codename everything in the email takes on a\n",
+ "slightly different meaning if we view it that way but that raises the question of why they didnt\n",
+ "share the intelligence with us in the meantime i tried to trackback through agatha s record to see\n",
+ "if there is anything to suggest that she might have been a double agent nothing mentioned in the\n",
+ "file raised a flag but i noticed two things in the attached vetting summary after her initial run in\n",
+ "with the german treasure hunters seeking the babylon stone she went on the run and papers reported\n",
+ "that she was a passenger on the titanic as you know she never boarded and used that tragedy as away\n",
+ "to disappear according to the report she did not reappear for over fourteen months when she was\n",
+ "recruited as an intelligence source in cairo for the british embassy that raises the question of\n",
+ "what she was doing for the year the other thing that struck a chord was the mention of mass our ie\n",
+ "george everest built a retreat there and his name came up when i was researching the security files\n",
+ "of charles babbage it seems that babbage was introduced to ideas from indian mathematics by everest\n",
+ "and this influenced the development of the difference engine and its successors mary boole wrote\n",
+ "about this in her letter indian thought and western science in the nineteenth century given what ch\n",
+ "wrote about the difference engine this might be more than a coincidence though perhaps i am reading\n",
+ "too much into it for the sake of our trainees i should say that the vetting report has been double\n",
+ "encrypted using avi genere with a second very simple twist i mention it because that threw me off\n",
+ "for a while i suggest that they reflect on what might be going on given that we are now trying to\n",
+ "avoid raising suspicion by the us and the lighthouse conspirators i think we should change our own\n",
+ "protocols so i have switched up to a transposition cipher i suggest you do the same next time though\n",
+ "you could try something else like a polybius square jodie\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(prettify(pa))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "6cecddd9",
+ "metadata": {
+ "Collapsed": "false"
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2525"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "open(plaintext_a_filename, 'w').write(prettify(pa))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "16210c33-3bcb-43c8-9189-d82eea7cf53b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "nittevg \n",
+ "\n",
+ "yllaunnaibdesiverebdluohsharofecnaraelcehttessarojamasatubnrecnocrofsdnuorgtnerruconeraerehtmsicafybdesoptaerhtetaidemmieromehtmorftcartsidotylekilyrevdnasmiadetatsstinideeccusotylekilnusatidedragerohwyratercesngierofehtybdetcejersawlasoporpehtmehtllatserofotredronistaerhterutufgniniltuostroperegnargnoleraperpotsawmiadetatsehtsrethgilpmalehtpuorgsihtdemankcinehsgninnalpdrawrofotdetacidedycnegaehtfohcnarbwenafohcnualehtgnidnemmocerrepapadetfardhahcinumrofgnivaelerofebevitaitininworehtadehcnualsawhcihwnetsimehclaeidnoitagitsevnitsetalrehotdeltahwsisihtylbamuserpdralizstsitneicsnairagnuhehtdnatforkcockciwdahcgnidulcnidoirepsihtgnirudsrotisivforebmunllamsadahehsnagebynamregninoissimtnerrucrehlitnudevilehserehwhciwneergnitnemtrapanakoothakuehtotnrutertnecerrehnosnoitareponeewtebdnanohtobsecruosernwonkrehhtiwtnetsisnocelytsefiladnasdneirfwefsahehseiruossamnigniyatsaidniniyadilohgniklawakootehsnoissimtnecertsomrehfodneehttaaisadnaacirfanisdoireptnacifingisdnepsotnwonksidnakuehtniesabtnenamreponsahhacilbuperramiewehtnignisilaicepseciffoeporueruonievitarepodaelaneebsahehsselliasrevecnisadnagaporpdnaegatobasgnitanidroocelihwsnoitisopsidpoortnostroperelbaulavdnaralugerdedivorpehserehwecnarfniseitudotdengissaersawehstcilfnocehtfokaerbtuoehtnotnavelehtniesitrepxerehfoesuaceboriacotdengissayllaitinisawdnarawtaergehtfokaerbtuoehterofebhtnomenonoitasinagroehtdeniojhaecnaraelcrehfoweivercidoirepdradnatsasisihtevobadnatercespottasseccallufsahdnasesacrojamnohhtiwylevisnetxedekrowsahehsasuehtdnakuehtnisnoitcennocgnortshtiwytinummocecnegilletniehtforebmemdedragerllewasihatnegaiiixxxmcmenujyrammusdleifhgihahtagaetadpugnittev\n"
+ ]
+ }
+ ],
+ "source": [
+ "word_b, score_b = vigenere_frequency_break(scb, fitness=Ptrigrams)\n",
+ "print(word_b, '\\n')\n",
+ "pb = vigenere_decipher(scb, word_b)\n",
+ "print(pb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "id": "595593e0-9b09-4ef8-974f-9969ff327941",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "vetting \n",
+ "\n",
+ "vettingupdateagathahighfieldsummaryjunemcmxxxiiiagentahisawellregardedmemberoftheintelligencecommunitywithstrongconnectionsintheukandtheusashehasworkedextensivelywithhonmajorcasesandhasfullaccessattopsecretandabovethisisastandardperiodicreviewofherclearanceahjoinedtheorganisationonemonthbeforetheoutbreakofthegreatwarandwasinitiallyassignedtocairobecauseofherexpertiseinthelevantontheoutbreakoftheconflictshewasreassignedtodutiesinfrancewheresheprovidedregularandvaluablereportsontroopdispositionswhilecoordinatingsabotageandpropagandasinceversaillesshehasbeenaleadoperativeinoureuropeofficespecialisingintheweimarrepublicahhasnopermanentbaseintheukandisknowntospendsignificantperiodsinafricaandasiaattheendofhermostrecentmissionshetookawalkingholidayinindiastayinginmassourieshehasfewfriendsandalifestyleconsistentwithherknownresourcesbothonandbetweenoperationsonherrecentreturntotheukahtookanapartmentingreenwichwheresheliveduntilhercurrentmissioningermanybeganshehadasmallnumberofvisitorsduringthisperiodincludingchadwickcockroftandthehungarianscientistszilardpresumablythisiswhatledtoherlatestinvestigationdiealchemistenwhichwaslaunchedatherowninitiativebeforeleavingformunichahdraftedapaperrecommendingthelaunchofanewbranchoftheagencydedicatedtoforwardplanningshenicknamedthisgroupthelamplightersthestatedaimwastopreparelongrangereportsoutliningfuturethreatsinordertoforestallthemtheproposalwasrejectedbytheforeignsecretarywhoregardeditasunlikelytosucceedinitsstatedaimsandverylikelytodistractfromthemoreimmediatethreatposedbyfacismtherearenocurrentgroundsforconcernbutasamajorassettheclearanceforahshouldberevisedbiannually\n"
+ ]
+ }
+ ],
+ "source": [
+ "word_b, score_b = vigenere_frequency_break(rscb, fitness=Ptrigrams)\n",
+ "print(word_b, '\\n')\n",
+ "pb = vigenere_decipher(rscb, word_b)\n",
+ "print(pb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "fe094361-7c85-40d9-952e-0c84abbcf903",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "vetting update agatha highfield summary june mcm xxxiii agent a his a well regarded member of the\n",
+ "intelligence community with strong connections in the uk and the usa she has worked extensively with\n",
+ "hon major cases and has full access at top secret and above this is a standard periodic review of\n",
+ "her clearance ah joined the organisation one month before the outbreak of the great war and was\n",
+ "initially assigned to cairo because of her expertise in the levant on the outbreak of the conflict\n",
+ "she was reassigned to duties in france where she provided regular and valuable reports on troop\n",
+ "dispositions while coordinating sabotage and propaganda since versailles she has been a lead\n",
+ "operative in our europe office specialising in the weimar republic ah has no permanent base in the\n",
+ "uk and is known to spend significant periods in africa and asia at the end of her most recent\n",
+ "mission she took a walking holiday in india staying in mass our ie she has few friends and a\n",
+ "lifestyle consistent with her known resources both on and between operations on her recent return to\n",
+ "the uk ah took an apartment in greenwich where she lived until her current mission in germany began\n",
+ "she had a small number of visitors during this period including chadwick cockroft and the hungarian\n",
+ "scientist szilard presumably this is what led to her latest investigation die alchemist en which was\n",
+ "launched at her own initiative before leaving for munich ah drafted a paper recommending the launch\n",
+ "of a new branch of the agency dedicated to forward planning she nicknamed this group the\n",
+ "lamplighters the stated aim was to prepare long range reports outlining future threats in order to\n",
+ "forestall them the proposal was rejected by the foreign secretary who regarded it as unlikely to\n",
+ "succeed in its stated aims and very likely to distract from the more immediate threat posed by\n",
+ "facism there are no current grounds for concern but as a major asset the clearance for ah should be\n",
+ "revised biannually\n"
+ ]
+ }
+ ],
+ "source": [
+ "pb = vigenere_decipher(rscb, word_b)\n",
+ "print(prettify(pb))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "d12a663c",
+ "metadata": {
+ "Collapsed": "false"
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1967"
+ ]
+ },
+ "execution_count": 24,
+ "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.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 = 6
+plaintext_a_filename = f'plaintext.{challenge_number}a.txt'
+plaintext_b_filename = f'plaintext.{challenge_number}b.txt'
+ciphertext_a_filename = f'ciphertext.{challenge_number}a.txt'
+ciphertext_b_filename = f'ciphertext.{challenge_number}b.txt'
+```
+
+```python Collapsed="false"
+ca = open(ciphertext_a_filename).read()
+cb = open(ciphertext_b_filename).read()
+
+sca = sanitise(ca)
+rsca = cat(reversed(sca))
+scb = sanitise(cb)
+rscb = cat(reversed(scb))
+```
+
+```python
+sca_counts = collections.Counter(sca)
+sca_counts
+```
+
+```python
+pd.Series(sca_counts).sort_index().plot.bar()
+```
+
+```python
+key_a, score_a = railfence_break(sca, fitness=Ptrigrams)
+print(key_a, '\n')
+pa = railfence_decipher(sca, key_a)
+print(pa)
+```
+
+```python
+(word_a, fill_a, empty_a), score_a = column_transposition_break(sca, fitness=Ptrigrams)
+print(word_a, fill_a, empty_a, '\n')
+pa = column_transposition_decipher(sca, word_a, fillcolumnwise=fill_a, emptycolumnwise=empty_a)
+print(pa)
+```
+
+```python
+transpositions_of('deacb')
+```
+
+```python
+transpositions[word_a]
+```
+
+```python
+print(prettify(pa))
+```
+
+```python Collapsed="false"
+open(plaintext_a_filename, 'w').write(prettify(pa))
+```
+
+```python
+word_b, score_b = vigenere_frequency_break(scb, fitness=Ptrigrams)
+print(word_b, '\n')
+pb = vigenere_decipher(scb, word_b)
+print(pb)
+```
+
+```python
+word_b, score_b = vigenere_frequency_break(rscb, fitness=Ptrigrams)
+print(word_b, '\n')
+pb = vigenere_decipher(rscb, word_b)
+print(pb)
+```
+
+```python
+pb = vigenere_decipher(rscb, word_b)
+print(prettify(pb))
+```
+
+```python Collapsed="false"
+open(plaintext_b_filename, 'w').write(prettify(pb))
+```
+
+```python Collapsed="false"
+
+```