From 7c5fd4061335669401bb298b5cec519b1f9afbc8 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Fri, 10 Nov 2017 15:35:08 +0000 Subject: [PATCH] Fully implemented Beaufort ciphers and breaking them --- 2017/2017-challenge5.ipynb | 238 ++++++++++++++++++++++++------------- cipher.py | 17 ++- cipherbreak.py | 54 ++++++++- 3 files changed, 223 insertions(+), 86 deletions(-) diff --git a/2017/2017-challenge5.ipynb b/2017/2017-challenge5.ipynb index 3160653..f2aa4c5 100644 --- a/2017/2017-challenge5.ipynb +++ b/2017/2017-challenge5.ipynb @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -92,7 +92,7 @@ "(24, -1733.3180566179738)" ] }, - "execution_count": 17, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -104,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -121,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -130,7 +130,7 @@ "((17, 21, True), -1723.2877779777489)" ] }, - "execution_count": 20, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -142,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -159,7 +159,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -168,7 +168,7 @@ "'etoainhsrdlumwycfgpbvkxjqz'" ] }, - "execution_count": 11, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -180,16 +180,16 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'yrkfdlbqpoisjcumzeawhtxgnv'" + "'yrkfdlbqpoisjcumzaetwhgxnv'" ] }, - "execution_count": 13, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -201,20 +201,20 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'A': 'p',\n", + "{'A': 'g',\n", " 'B': 'h',\n", " 'C': 'w',\n", " 'D': 'i',\n", - " 'E': 'g',\n", + " 'E': 'p',\n", " 'F': 'a',\n", - " 'G': 'j',\n", - " 'H': 'v',\n", + " 'G': 'x',\n", + " 'H': 'k',\n", " 'I': 'l',\n", " 'J': 'm',\n", " 'K': 'o',\n", @@ -226,16 +226,16 @@ " 'Q': 's',\n", " 'R': 't',\n", " 'S': 'u',\n", - " 'T': 'k',\n", + " 'T': 'b',\n", " 'U': 'y',\n", " 'V': 'z',\n", - " 'W': 'b',\n", - " 'X': 'x',\n", + " 'W': 'v',\n", + " 'X': 'j',\n", " 'Y': 'e',\n", " 'Z': 'f'}" ] }, - "execution_count": 14, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -247,14 +247,14 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "mirbi mjnda ehisp noeai rrake daose lwuvi sclio oedgu tshed adotm iveth ereod exknu sthel nwils titan othao vshem ibhik egeeo vadoi ccedg utthe rehis geeoo nrios nmdem iodio dther eason thaop muwht npnno herrn nmhid geeor iosiw vedio dshel efton messi pegut snmet haopt ellsm eshea snvio dyesh nuldm nkeno athao vshem ibhik eclio oedth asmei oyhal eahik ethed nwume otjnd aeyio tedfr nmlno dnoad notvo nyhny shevo eygut thefa fthwh icter yisha ddeoa oiwik atbao istno elaot elaos nmere miaos aothe eches usrnn mitth egrat ashmu seuma tyise owrbc tedus aopio nther cnlbi lchig etaww acher aokeo tedao theoa oetee othwe oturb aisve dthem useum tntes tatio dthed nwume otasi utheo tawsn apues sthea mcera ilwac hersw hnnlr eillb hidmn kedno cerhi csash nuldo thike geeos urcra sedif terth edasw nkerb itgnd rumgu tatle ikesm eynod eraop yhite lseth ebdek elnce dnoen ddfei turey isifr aexer uooao prnuo dthre esade snfth elaot elwno sasta opnfi saopl ernyn fgliw viody hatet alest hitth emuse umtha ovyer eidde daoth ernmi ocera ndthe breid aoseq ueowe yyggy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg gyyyg yygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygyyg yyygy gggyg ggygg gyggg ygggy gggyg ggygg gyggg ygggy gggyg ggygg gyggg ygggy gggyg ggygg gyggg ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yygyy ygyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy ygyyy gyyyy gyyyg ggyyy yyggg yyygy yygyy ygyyy gyyyy gggyy gyyyg ygggy yyggg gyygg gyyyg ggyyg ggygy yygyy yygyg yygyy gyyyg yyyyy gygyy ggyyg yygyg yyyyg yyygg yggyg yygyy gyyyy ygyyg yyygy yyygy yygyy ygyyg yyygy gyyyg ygyyy yygyy ygygy gygyg yyygy yygyy ygygy gygyy gyygy yyyyg yyygy ygyyy ygyyg yyygy yyggg ggygg ggyyg yyyyy ggggg ygygy gyggg ggyyy gyyyg yyygy ggggy ygggy yyggg gyyyg yyyyg yyygy yygyy gyyyg ygygy yygyy yyygy yygyg ygygy gyyyg yyygy yygyy ygygy yyyyg yyyyy gygyy yygyy yygyy gyyyg yyygy yygyg yygyy ygyyy ygyyy gygyy ggygy yygyy ygyyy gyyyg ygyyy yygyy yyygy ygyyy gyyyy gyyyg yyygy ygyyy gygyy ygyyy gggyg yyygy gyyyg ygyyy gyygg gyygy yygyg yyyyy ggggy ygyyy gyggg yyggg ygyyy gyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy gyyyg yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yygyy ygygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg ygyyy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy gygyg ygygy yygyy gggyg ggygg gyggg ygggy gggyg ggygg gyggg ygggy gggyg ggygg gyggg ygggy gggyg ggygg gyggg yygyy ygyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyy gyyyg yyygy yygyy ygyyg yyahi keuse dgfnr thegl iwvta lesio dyfnr theyh ateno esatt nnvme iyhal etnfa puren utthi tthef raexe asste pionp richb wnowe ilaop theve bynrd fnrth ewach eraow hicte rfake yathn utjnd aeaim ontsu reyhe retnp noezt there ireno lbtyn cnssa galat aesis firis awios eegut ahike onade iyher enoen fthem asiod isfir isawi otell onnoe elsev onyse ather snapu essay allhe idfnr nlbmc aisee bnuth ere\n" + "mirvi mxnda ehisg noeai rrabe daose lwuki sclio oedpu tshed adotm iketh ereod ejbnu sthel nwils titan othao kshem ivhib epeeo kadoi ccedp utthe rehis peeoo nrios nmdem iodio dther eason thaog muwht ngnno herrn nmhid peeor iosiw kedio dshel efton messi geput snmet haogt ellsm eshea snkio dyesh nuldm nbeno athao kshem ivhib eclio oedth asmei oyhal eahib ethed nwume otxnd aeyio tedfr nmlno dnoad notko nyhny sheko eyput thefa fthwh icter yisha ddeoa oiwib atvao istno elaot elaos nmere miaos aothe eches usrnn mitth eprat ashmu seuma tyise owrvc tedus aogio nther cnlvi lchip etaww acher aobeo tedao theoa oetee othwe oturv aiske dthem useum tntes tatio dthed nwume otasi utheo tawsn agues sthea mcera ilwac hersw hnnlr eillv hidmn bedno cerhi csash nuldo thibe peeos urcra sedif terth edasw nberv itpnd rumpu tatle ibesm eynod eraog yhite lseth evdeb elnce dnoen ddfei turey isifr aejer uooao grnuo dthre esade snfth elaot elwno sasta ognfi saogl ernyn fpliw kiody hatet alest hitth emuse umtha okyer eidde daoth ernmi ocera ndthe vreid aoseq ueowe yyppy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp pyyyp yypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypyyp yyypy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yypyy ypyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy ypyyy pyyyy pyyyp ppyyy yyppp yyypy yypyy ypyyy pyyyy pppyy pyyyp ypppy yyppp pyypp pyyyp ppyyp ppypy yypyy yypyp yypyy pyyyp yyyyy pypyy ppyyp yypyp yyyyp yyypp yppyp yypyy pyyyy ypyyp yyypy yyypy yypyy ypyyp yyypy pyyyp ypyyy yypyy ypypy pypyp yyypy yypyy ypypy pypyy pyypy yyyyp yyypy ypyyy ypyyp yyypy yyppp ppypp ppyyp yyyyy ppppp ypypy pyppp ppyyy pyyyp yyypy ppppy ypppy yyppp pyyyp yyyyp yyypy yypyy pyyyp ypypy yypyy yyypy yypyp ypypy pyyyp yyypy yypyy ypypy yyyyp yyyyy pypyy yypyy yypyy pyyyp yyypy yypyp yypyy ypyyy ypyyy pypyy ppypy yypyy ypyyy pyyyp ypyyy yypyy yyypy ypyyy pyyyy pyyyp yyypy ypyyy pypyy ypyyy pppyp yyypy pyyyp ypyyy pyypp pyypy yypyp yyyyy ppppy ypyyy pyppp yyppp ypyyy pyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy pyyyp yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yypyy ypypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp ypyyy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy yypyy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp yypyy ypyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyp yyahi beuse dpfnr thepl iwkta lesio dyfnr theyh ateno esatt nnkme iyhal etnfa guren utthi tthef raeje asste giong richv wnowe ilaog theke vynrd fnrth ewach eraow hicte rfabe yathn utxnd aeaim ontsu reyhe retng noezt there ireno lvtyn cnssa palat aesis firis awios eeput ahibe onade iyher enoen fthem asiod isfir isawi otell onnoe elsek onyse ather snagu essay allhe idfnr nlvmc aisee vnuth ere\n" ] } ], @@ -265,7 +265,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -345,7 +345,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -379,7 +379,7 @@ " 'Z': 'f'}" ] }, - "execution_count": 74, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -390,7 +390,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -424,7 +424,7 @@ " 'z': 'X'}" ] }, - "execution_count": 75, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -435,7 +435,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -486,7 +486,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -495,7 +495,7 @@ "3362" ] }, - "execution_count": 33, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -506,7 +506,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -535,7 +535,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -544,7 +544,7 @@ "1577" ] }, - "execution_count": 4, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -555,7 +555,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -564,7 +564,7 @@ "26" ] }, - "execution_count": 5, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -575,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -595,13 +595,13 @@ " ('x', 48),\n", " ('h', 47),\n", " ('g', 41),\n", - " ('u', 38),\n", " ('l', 38),\n", + " ('u', 38),\n", " ('k', 35),\n", " ('b', 34),\n", " ('c', 34),\n", - " ('t', 33),\n", " ('z', 33),\n", + " ('t', 33),\n", " ('q', 32),\n", " ('s', 29),\n", " ('f', 25),\n", @@ -609,7 +609,7 @@ " ('d', 22)]" ] }, - "execution_count": 6, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -620,7 +620,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -629,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -638,7 +638,7 @@ "[('i', 'n'), ('n', 'o'), ('o', 'o'), ('o', 'a'), ('a', 'd')]" ] }, - "execution_count": 8, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -649,7 +649,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -658,7 +658,7 @@ "('fwruffnquevmp', -1750.4576000271347)" ] }, - "execution_count": 9, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -670,7 +670,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -679,7 +679,7 @@ "'nieyqmhcenwlqvchdporosweiohtsshreoihpsvrvusdcostmjezkdeytdhrtasupknropbklngeutgnssthjhhnowgbdwvucncdvofhbdltfpvobiuicirayodpwkpoutibtgcenuhpwachchnbrjydhsfvhqszeuvdcpswatvzmxhsiigkobvcagqcdikfstrvkfggbdkvcvstuvufienwiniasbcecmvdwemkwgtnsyjridowjamhuhnrvxssgewikqxpxhashvwvteulpavioctweavlhtikkkximoikdloikrwswfiojrynulrsgtoktknqcporlruoigivdpeddhrntdmrnucnrioiuetpdnftaipjrewjqtercxzvydhiswrtrneonknnfsyrifcdhedoweptjrechehcptdcehirohbcpniloorntrrrtohgeoandszehilxywfqkrgnphglvcojfbetcietpqmfetkalnahiwixdppersmrihrctseahkhtifbokasoozrjgvvkehjsufarunbrtiswzdmriwcrovhdsdeihdteiiustmjupvkhdiisibjloyrdpyxkusdlwfpsehvevdoiudppehzgvcewnhifrvkfggbdkbidptartnotloihpseehrdipeotmlwbcousicucctsktsrlritcanhpdmrehuinioiuuwirsxtanvjshfwyrkacfihfctdipytegvprdowhfldhycrqhfctswdbnagevitctsufsrofoccprycjgnifeikrthnowgcedfedjwiisdtihszeecfvlwjqgehoeicssaqflthagmncpvvifnreneoiioiulytddhuhkrtzsdpevphodehkctsvfhltophksiepsgcohnrnuseajettlhdwhiepjwcenbtbuecihpijncohouidiqjikpovimvsrfridohvchdporhrmhlpnikpacvjiswwgszeyxrcpragclkvxbporlruoigoviferifridicrskiporsyypwgprszenephnicczvttucvqesuiivqleesvfrhcfgchuswrocjslotcnxtiiswkoieatruninitradpaortylcouoahdpehgukcvlrmrafrntaovetrxvyinpenvniquglltisxgy'" ] }, - "execution_count": 10, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -690,16 +690,16 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "('vejgvvnkgwfol', -1750.4576000271347)" + "('arcanaimperii', -1506.8637359274674)" ] }, - "execution_count": 11, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -711,16 +711,16 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'nieyqmhcenwlqvchdporosweiohtsshreoihpsvrvusdcostmjezkdeytdhrtasupknropbklngeutgnssthjhhnowgbdwvucncdvofhbdltfpvobiuicirayodpwkpoutibtgcenuhpwachchnbrjydhsfvhqszeuvdcpswatvzmxhsiigkobvcagqcdikfstrvkfggbdkvcvstuvufienwiniasbcecmvdwemkwgtnsyjridowjamhuhnrvxssgewikqxpxhashvwvteulpavioctweavlhtikkkximoikdloikrwswfiojrynulrsgtoktknqcporlruoigivdpeddhrntdmrnucnrioiuetpdnftaipjrewjqtercxzvydhiswrtrneonknnfsyrifcdhedoweptjrechehcptdcehirohbcpniloorntrrrtohgeoandszehilxywfqkrgnphglvcojfbetcietpqmfetkalnahiwixdppersmrihrctseahkhtifbokasoozrjgvvkehjsufarunbrtiswzdmriwcrovhdsdeihdteiiustmjupvkhdiisibjloyrdpyxkusdlwfpsehvevdoiudppehzgvcewnhifrvkfggbdkbidptartnotloihpseehrdipeotmlwbcousicucctsktsrlritcanhpdmrehuinioiuuwirsxtanvjshfwyrkacfihfctdipytegvprdowhfldhycrqhfctswdbnagevitctsufsrofoccprycjgnifeikrthnowgcedfedjwiisdtihszeecfvlwjqgehoeicssaqflthagmncpvvifnreneoiioiulytddhuhkrtzsdpevphodehkctsvfhltophksiepsgcohnrnuseajettlhdwhiepjwcenbtbuecihpijncohouidiqjikpovimvsrfridohvchdporhrmhlpnikpacvjiswwgszeyxrcpragclkvxbporlruoigoviferifridicrskiporsyypwgprszenephnicczvttucvqesuiivqleesvfrhcfgchuswrocjslotcnxtiiswkoieatruninitradpaortylcouoahdpehgukcvlrmrafrntaovetrxvyinpenvniquglltisxgy'" + "'inhisjournaldatedtheidesofoctoberintheyearoftheconsulshipsofcaeceliustulliuscapitopomponianusplotiusfirmusandgaiuscorneliusgallicanusagricolawrotethemysteryofthebattleatcamulodonumisatlastsolvedcalgacusmaybeabarbariannowbuthewasaromancitizenthenwhobetrayedusallforloveofabarbarianithastakenallmyskillsasaleaderofmentokeephimalivethelegionnairesspendtheireveningsdesigningnewandcruelwaystoexecutehiminrevengefortheshamehebroughtuponusbuthislifeispreciousitistheonlycardlefttoplayinoursearchforsalvationandthereturnofthestolenaquilaeifwecanalsorecoverthecodexthenperhapsitslosscanbeconcealedandourliveswillbesparedreleasingtheromantraitorcalgacusmusthavestuckintheproudagricolasthroatbuthemadeapactwiththeremainingcaledoniiandtravellednorthtoexchangetheprisonerfortheaquilaeandthecodexbutthecunningcaledoniantribesmansetanothertrapandpresentedagricolawithaforgerycunninglyassembledwithpagesfromthebooksstolenwhenthetriberansackedmonsgraupiusfortoolongthesonsofromehadunderestimatedthepeopleinbritanniaandwhiletheaquilaofthelegionhadbeenrestoredbytheexchangetheirhonourwasnotagricolafacedareturntoromehumiliationandalmostcertaindeaththesixthchapterofmytaleofwoeisguardedbylightningbullandoak'" ] }, - "execution_count": 12, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -731,7 +731,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -740,7 +740,7 @@ "'a'" ] }, - "execution_count": 13, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -751,7 +751,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -760,7 +760,7 @@ "'zyxwvutsrqponmlkjihgfedcba'" ] }, - "execution_count": 14, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -771,7 +771,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -780,7 +780,7 @@ "'hveheifhbiicuzbbcfgvvnzafwnkqnndivxopvpdionrsyrmjvjlkaehbrfsmvmtvkqrrftcyspatroqqnbndcyiqretamkaszhcaqidtaxmpfrvenkfimmihgrxnvgqtrmcpzsqzpygininbbstddlcomipnnqgqargdgmrkbijtxnubxpuzjzbizesjbvqmutztdzotjzktjvraioamqznxiwnstbedizjnbjurebqqhldegrzvnynjbsdzprnparcknlqxnmryaisrqjxquzevdcijkzsbmmkczinszckaxrmkvnnzzfwlmksajvrzcqdrkqsdfgvyobqfemifqqrjcoilkydqodhdevxbauvrqdmumxaorieubzrdxvrlcowvodkrsqgzzsizvmdvddrnigrzayrlmednqfhqcblgnvrrntkusntzwdqpoddtvypazkhaqgqneyixiiukmcsfngyktqeftzpdmqtupjzjrkdxsunenxybyvqmqtdmfsdcmjkntbmmplvvvmzwvmzzzzcfymmtfumostdtbnzfkydvmddgrccdbjcnapbmmsrmjvtvztbcmmubemtzmdathxksrckiivczbkqzjvxbbyvqwjzzsinsowitztdzotjzenbyrumpsgbbvxopvgqwrcmfivmjtrjsponmsshdcmdrcmxombkjsopkydzblmhevxbkrcdllmuhranozrmdtidpmfedcbfvwkezzfvgrzxizrwkddefedcmrhtqizqzeqdcmtfcmuagskuoxceehvdbmkvqyiqreszfaqrdnxnmkrmwqgqqkekkieuozbrqmkrnvoizbwizihkukawixdzvbgmevxbtprrablnkvqgdbygzobrrqfzdcmsfnsprfncrxrpvespbsdhsrbvvjrbsbcynefqmilghcpeaqkbygwexspbramjbpmwdvgiatzcveonbzdzbbcfgvcojxcvhvyqusraxdireceehxdkuovylzkilefgvyobqfegiaaqdeeonbfidlyxfgvrhxprefmqgqhiuyiwlivipmasrtbdkfcznxbqcreoocieswonydyhwdtzrsqlmmmunvhwjkbmosmheqovbykgmphjsyprvxkvqwclksryojnnfdqpfgziqoyjpchoeszhetlptcrmllzw'" ] }, - "execution_count": 15, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -792,7 +792,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -801,7 +801,7 @@ "('zixzmzrnkvirr', -1506.8637359274674)" ] }, - "execution_count": 16, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -813,7 +813,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -822,7 +822,7 @@ "'inhisjournaldatedtheidesofoctoberintheyearoftheconsulshipsofcaeceliustulliuscapitopomponianusplotiusfirmusandgaiuscorneliusgallicanusagricolawrotethemysteryofthebattleatcamulodonumisatlastsolvedcalgacusmaybeabarbariannowbuthewasaromancitizenthenwhobetrayedusallforloveofabarbarianithastakenallmyskillsasaleaderofmentokeephimalivethelegionnairesspendtheireveningsdesigningnewandcruelwaystoexecutehiminrevengefortheshamehebroughtuponusbuthislifeispreciousitistheonlycardlefttoplayinoursearchforsalvationandthereturnofthestolenaquilaeifwecanalsorecoverthecodexthenperhapsitslosscanbeconcealedandourliveswillbesparedreleasingtheromantraitorcalgacusmusthavestuckintheproudagricolasthroatbuthemadeapactwiththeremainingcaledoniiandtravellednorthtoexchangetheprisonerfortheaquilaeandthecodexbutthecunningcaledoniantribesmansetanothertrapandpresentedagricolawithaforgerycunninglyassembledwithpagesfromthebooksstolenwhenthetriberansackedmonsgraupiusfortoolongthesonsofromehadunderestimatedthepeopleinbritanniaandwhiletheaquilaofthelegionhadbeenrestoredbytheexchangetheirhonourwasnotagricolafacedareturntoromehumiliationandalmostcertaindeaththesixthchapterofmytaleofwoeisguardedbylightningbullandoak'" ] }, - "execution_count": 17, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -833,7 +833,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -842,7 +842,7 @@ "'arcanaimperii'" ] }, - "execution_count": 18, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -853,7 +853,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -884,7 +884,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -893,7 +893,7 @@ "1465" ] }, - "execution_count": 101, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -904,15 +904,15 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ - "def b2_encipher(message, keyword):\n", - " \"\"\"Vigenere encipher\n", + "def beaufort_encipher(message, keyword):\n", + " \"\"\"Beaufort encipher\n", "\n", - " >>> vigenere_encipher('hello', 'abc')\n", - " 'hfnlp'\n", + " >>> beaufort_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii')\n", + " 'sevsvrusyrrxfayyxuteemazudmpjmmwr'\n", " \"\"\"\n", " shifts = [pos(l) for l in sanitise(keyword)]\n", " pairs = zip(message, cycle(shifts))\n", @@ -921,7 +921,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -930,27 +930,27 @@ "'sevsvrusyrrxfayyxuteemazudmpjmmwr'" ] }, - "execution_count": 22, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "b2_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii')" + "beaufort_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii')" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ - "b2_decipher = b2_encipher" + "beaufort_decipher = beaufort_encipher" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -959,13 +959,87 @@ "'inhisjournaldatedtheidesofoctober'" ] }, - "execution_count": 26, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "beaufort_decipher('sevsvrusyrrxfayyxuteemazudmpjmmwr', 'arcanaimperii')" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [], + "source": [ + "# def beaufort_sub_break(message, fitness=Pletters):\n", + "# best_shift = 0\n", + "# best_fit = float('-inf')\n", + "# for key in range(26):\n", + "# plaintext = [unpos(key - pos(l)) for l in message]\n", + "# fit = fitness(plaintext)\n", + "# logger.debug('Beaufort sub break attempt using key {0} gives fit of {1} '\n", + "# 'and decrypt starting: {2}'.format(key, fit,\n", + "# plaintext[:50]))\n", + "# if fit > best_fit:\n", + "# best_fit = fit\n", + "# best_key = key\n", + "# logger.info('Beaufort sub break best fit: key {0} gives fit of {1} and '\n", + "# 'decrypt starting: {2}'.format(best_key, best_fit, \n", + "# cat([unpos(best_key - pos(l)) for l in message[:50]])))\n", + "# return best_key, best_fit" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "# def beaufort_frequency_break(message, max_key_length=20, fitness=Pletters):\n", + "# \"\"\"Breaks a Beaufort cipher with frequency analysis\n", + "\n", + "# >>> beaufort_frequency_break(beaufort_encipher(sanitise(\"It is time to \" \\\n", + "# \"run. She is ready and so am I. I stole Daniel's pocketbook this \" \\\n", + "# \"afternoon when he left his jacket hanging on the easel in the \" \\\n", + "# \"attic. I jump every time I hear a footstep on the stairs, \" \\\n", + "# \"certain that the theft has been discovered and that I will \" \\\n", + "# \"be caught. The SS officer visits less often now \" \\\n", + "# \"that he is sure\"), 'florence')) # doctest: +ELLIPSIS\n", + "# ('florence', -307.5473096791...)\n", + "# \"\"\"\n", + "# def worker(message, key_length, fitness):\n", + "# splits = every_nth(message, key_length)\n", + "# key = cat([unpos(beaufort_sub_break(s)[0]) for s in splits])\n", + "# plaintext = beaufort_decipher(message, key)\n", + "# fit = fitness(plaintext)\n", + "# return key, fit\n", + "# sanitised_message = sanitise(message)\n", + "# results = starmap(worker, [(sanitised_message, i, fitness)\n", + "# for i in range(1, max_key_length+1)])\n", + "# return max(results, key=lambda k: k[1])" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('arcanaimperii', -1506.8637359274674)" + ] + }, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "b2_decipher('sevsvrusyrrxfayyxuteemazudmpjmmwr', 'arcanaimperii')" + "beaufort_frequency_break(cb)" ] }, { @@ -992,7 +1066,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.3" + "version": "3.5.2" } }, "nbformat": 4, diff --git a/cipher.py b/cipher.py index 4c3f14b..b141369 100644 --- a/cipher.py +++ b/cipher.py @@ -395,8 +395,21 @@ def vigenere_decipher(message, keyword): pairs = zip(message, cycle(shifts)) return cat([caesar_decipher_letter(l, k) for l, k in pairs]) -beaufort_encipher=vigenere_decipher -beaufort_decipher=vigenere_encipher + +def beaufort_encipher(message, keyword): + """Beaufort encipher + + >>> beaufort_encipher('inhisjournaldatedtheidesofoctober', 'arcanaimperii') + 'sevsvrusyrrxfayyxuteemazudmpjmmwr' + """ + shifts = [pos(l) for l in sanitise(keyword)] + pairs = zip(message, cycle(shifts)) + return cat([unpos(k - pos(l)) for l, k in pairs]) + +beaufort_decipher = beaufort_encipher + +beaufort_variant_encipher=vigenere_decipher +beaufort_variant_decipher=vigenere_encipher def polybius_grid(keyword, column_order, row_order, letters_to_merge=None, diff --git a/cipherbreak.py b/cipherbreak.py index 669d133..a2eecad 100644 --- a/cipherbreak.py +++ b/cipherbreak.py @@ -311,6 +311,33 @@ def vigenere_frequency_break(message, max_key_length=20, fitness=Pletters): return max(results, key=lambda k: k[1]) +def beaufort_sub_break(message, fitness=Pletters): + """Breaks one chunk of a Beaufort cipher with frequency analysis + + >>> beaufort_sub_break('samwpplggnnmmyaazgympjapopnwiywwomwspgpjmefwmawx' \ + 'jafjhxwwwdigxshnlywiamhyshtasxptwueahhytjwsn') # doctest: +ELLIPSIS + (0, -117.4492...) + >>> beaufort_sub_break('eyprzjjzznxymrygryjqmqhznjrjjapenejznawngnnezgza' \ + 'dgndknaogpdjneadadazlhkhxkryevrronrmdjnndjlo') # doctest: +ELLIPSIS + (17, -114.9598...) + """ + best_shift = 0 + best_fit = float('-inf') + for key in range(26): + plaintext = [unpos(key - pos(l)) for l in message] + fit = fitness(plaintext) + logger.debug('Beaufort sub break attempt using key {0} gives fit of {1} ' + 'and decrypt starting: {2}'.format(key, fit, + plaintext[:50])) + if fit > best_fit: + best_fit = fit + best_key = key + logger.info('Beaufort sub break best fit: key {0} gives fit of {1} and ' + 'decrypt starting: {2}'.format(best_key, best_fit, + cat([unpos(best_key - pos(l)) for l in message[:50]]))) + return best_key, best_fit + + def beaufort_frequency_break(message, max_key_length=20, fitness=Pletters): """Breaks a Beaufort cipher with frequency analysis @@ -323,11 +350,35 @@ def beaufort_frequency_break(message, max_key_length=20, fitness=Pletters): "that he is sure"), 'florence')) # doctest: +ELLIPSIS ('florence', -307.5473096791...) """ + def worker(message, key_length, fitness): + splits = every_nth(message, key_length) + key = cat([unpos(beaufort_sub_break(s)[0]) for s in splits]) + plaintext = beaufort_decipher(message, key) + fit = fitness(plaintext) + return key, fit + sanitised_message = sanitise(message) + results = starmap(worker, [(sanitised_message, i, fitness) + for i in range(1, max_key_length+1)]) + return max(results, key=lambda k: k[1]) + + +def beaufort_variant_frequency_break(message, max_key_length=20, fitness=Pletters): + """Breaks a Beaufort cipher with frequency analysis + + >>> beaufort_variant_frequency_break(beaufort_variant_encipher(sanitise("It is time to " \ + "run. She is ready and so am I. I stole Daniel's pocketbook this " \ + "afternoon when he left his jacket hanging on the easel in the " \ + "attic. I jump every time I hear a footstep on the stairs, " \ + "certain that the theft has been discovered and that I will " \ + "be caught. The SS officer visits less often now " \ + "that he is sure"), 'florence')) # doctest: +ELLIPSIS + ('florence', -307.5473096791...) + """ def worker(message, key_length, fitness): splits = every_nth(sanitised_message, key_length) key = cat([chr(-caesar_break(s)[0] % 26 + ord('a')) for s in splits]) - plaintext = beaufort_decipher(message, key) + plaintext = beaufort_variant_decipher(message, key) fit = fitness(plaintext) return key, fit sanitised_message = sanitise(message) @@ -335,7 +386,6 @@ def beaufort_frequency_break(message, max_key_length=20, fitness=Pletters): for i in range(1, max_key_length+1)]) return max(results, key=lambda k: k[1]) - def polybius_break_mp(message, column_labels, row_labels, letters_to_merge=None, wordlist=keywords, fitness=Pletters, -- 2.34.1