Fully implemented Beaufort ciphers and breaking them
authorNeil Smith <neil.git@njae.me.uk>
Fri, 10 Nov 2017 15:35:08 +0000 (15:35 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 10 Nov 2017 15:35:08 +0000 (15:35 +0000)
2017/2017-challenge5.ipynb
cipher.py
cipherbreak.py

index 31606534bda08aefa6e14c27a29168a896a1664d..f2aa4c5111789da9ffc44b02800e6289a8cb77de 100644 (file)
@@ -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"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [
     {
        "((17, 21, True), -1723.2877779777489)"
       ]
      },
-     "execution_count": 20,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 8,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 9,
    "metadata": {},
    "outputs": [
     {
        "'etoainhsrdlumwycfgpbvkxjqz'"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 9,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "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"
     }
   },
   {
    "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",
        " '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"
     }
   },
   {
    "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"
      ]
     }
    ],
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 13,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 74,
+   "execution_count": 14,
    "metadata": {},
    "outputs": [
     {
        " 'Z': 'f'}"
       ]
      },
-     "execution_count": 74,
+     "execution_count": 14,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 75,
+   "execution_count": 15,
    "metadata": {},
    "outputs": [
     {
        " 'z': 'X'}"
       ]
      },
-     "execution_count": 75,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 76,
+   "execution_count": 16,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 17,
    "metadata": {},
    "outputs": [
     {
        "3362"
       ]
      },
-     "execution_count": 33,
+     "execution_count": 17,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 18,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 19,
    "metadata": {},
    "outputs": [
     {
        "1577"
       ]
      },
-     "execution_count": 4,
+     "execution_count": 19,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 20,
    "metadata": {},
    "outputs": [
     {
        "26"
       ]
      },
-     "execution_count": 5,
+     "execution_count": 20,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 21,
    "metadata": {},
    "outputs": [
     {
        " ('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",
        " ('d', 22)]"
       ]
      },
-     "execution_count": 6,
+     "execution_count": 21,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 22,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 23,
    "metadata": {},
    "outputs": [
     {
        "[('i', 'n'), ('n', 'o'), ('o', 'o'), ('o', 'a'), ('a', 'd')]"
       ]
      },
-     "execution_count": 8,
+     "execution_count": 23,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 24,
    "metadata": {},
    "outputs": [
     {
        "('fwruffnquevmp', -1750.4576000271347)"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 24,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 25,
    "metadata": {},
    "outputs": [
     {
        "'nieyqmhcenwlqvchdporosweiohtsshreoihpsvrvusdcostmjezkdeytdhrtasupknropbklngeutgnssthjhhnowgbdwvucncdvofhbdltfpvobiuicirayodpwkpoutibtgcenuhpwachchnbrjydhsfvhqszeuvdcpswatvzmxhsiigkobvcagqcdikfstrvkfggbdkvcvstuvufienwiniasbcecmvdwemkwgtnsyjridowjamhuhnrvxssgewikqxpxhashvwvteulpavioctweavlhtikkkximoikdloikrwswfiojrynulrsgtoktknqcporlruoigivdpeddhrntdmrnucnrioiuetpdnftaipjrewjqtercxzvydhiswrtrneonknnfsyrifcdhedoweptjrechehcptdcehirohbcpniloorntrrrtohgeoandszehilxywfqkrgnphglvcojfbetcietpqmfetkalnahiwixdppersmrihrctseahkhtifbokasoozrjgvvkehjsufarunbrtiswzdmriwcrovhdsdeihdteiiustmjupvkhdiisibjloyrdpyxkusdlwfpsehvevdoiudppehzgvcewnhifrvkfggbdkbidptartnotloihpseehrdipeotmlwbcousicucctsktsrlritcanhpdmrehuinioiuuwirsxtanvjshfwyrkacfihfctdipytegvprdowhfldhycrqhfctswdbnagevitctsufsrofoccprycjgnifeikrthnowgcedfedjwiisdtihszeecfvlwjqgehoeicssaqflthagmncpvvifnreneoiioiulytddhuhkrtzsdpevphodehkctsvfhltophksiepsgcohnrnuseajettlhdwhiepjwcenbtbuecihpijncohouidiqjikpovimvsrfridohvchdporhrmhlpnikpacvjiswwgszeyxrcpragclkvxbporlruoigoviferifridicrskiporsyypwgprszenephnicczvttucvqesuiivqleesvfrhcfgchuswrocjslotcnxtiiswkoieatruninitradpaortylcouoahdpehgukcvlrmrafrntaovetrxvyinpenvniquglltisxgy'"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 25,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "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"
     }
   },
   {
    "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"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 28,
    "metadata": {},
    "outputs": [
     {
        "'a'"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 28,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 29,
    "metadata": {},
    "outputs": [
     {
        "'zyxwvutsrqponmlkjihgfedcba'"
       ]
      },
-     "execution_count": 14,
+     "execution_count": 29,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 30,
    "metadata": {},
    "outputs": [
     {
        "'hveheifhbiicuzbbcfgvvnzafwnkqnndivxopvpdionrsyrmjvjlkaehbrfsmvmtvkqrrftcyspatroqqnbndcyiqretamkaszhcaqidtaxmpfrvenkfimmihgrxnvgqtrmcpzsqzpygininbbstddlcomipnnqgqargdgmrkbijtxnubxpuzjzbizesjbvqmutztdzotjzktjvraioamqznxiwnstbedizjnbjurebqqhldegrzvnynjbsdzprnparcknlqxnmryaisrqjxquzevdcijkzsbmmkczinszckaxrmkvnnzzfwlmksajvrzcqdrkqsdfgvyobqfemifqqrjcoilkydqodhdevxbauvrqdmumxaorieubzrdxvrlcowvodkrsqgzzsizvmdvddrnigrzayrlmednqfhqcblgnvrrntkusntzwdqpoddtvypazkhaqgqneyixiiukmcsfngyktqeftzpdmqtupjzjrkdxsunenxybyvqmqtdmfsdcmjkntbmmplvvvmzwvmzzzzcfymmtfumostdtbnzfkydvmddgrccdbjcnapbmmsrmjvtvztbcmmubemtzmdathxksrckiivczbkqzjvxbbyvqwjzzsinsowitztdzotjzenbyrumpsgbbvxopvgqwrcmfivmjtrjsponmsshdcmdrcmxombkjsopkydzblmhevxbkrcdllmuhranozrmdtidpmfedcbfvwkezzfvgrzxizrwkddefedcmrhtqizqzeqdcmtfcmuagskuoxceehvdbmkvqyiqreszfaqrdnxnmkrmwqgqqkekkieuozbrqmkrnvoizbwizihkukawixdzvbgmevxbtprrablnkvqgdbygzobrrqfzdcmsfnsprfncrxrpvespbsdhsrbvvjrbsbcynefqmilghcpeaqkbygwexspbramjbpmwdvgiatzcveonbzdzbbcfgvcojxcvhvyqusraxdireceehxdkuovylzkilefgvyobqfegiaaqdeeonbfidlyxfgvrhxprefmqgqhiuyiwlivipmasrtbdkfcznxbqcreoocieswonydyhwdtzrsqlmmmunvhwjkbmosmheqovbykgmphjsyprvxkvqwclksryojnnfdqpfgziqoyjpchoeszhetlptcrmllzw'"
       ]
      },
-     "execution_count": 15,
+     "execution_count": 30,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 31,
    "metadata": {},
    "outputs": [
     {
        "('zixzmzrnkvirr', -1506.8637359274674)"
       ]
      },
-     "execution_count": 16,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 32,
    "metadata": {},
    "outputs": [
     {
        "'inhisjournaldatedtheidesofoctoberintheyearoftheconsulshipsofcaeceliustulliuscapitopomponianusplotiusfirmusandgaiuscorneliusgallicanusagricolawrotethemysteryofthebattleatcamulodonumisatlastsolvedcalgacusmaybeabarbariannowbuthewasaromancitizenthenwhobetrayedusallforloveofabarbarianithastakenallmyskillsasaleaderofmentokeephimalivethelegionnairesspendtheireveningsdesigningnewandcruelwaystoexecutehiminrevengefortheshamehebroughtuponusbuthislifeispreciousitistheonlycardlefttoplayinoursearchforsalvationandthereturnofthestolenaquilaeifwecanalsorecoverthecodexthenperhapsitslosscanbeconcealedandourliveswillbesparedreleasingtheromantraitorcalgacusmusthavestuckintheproudagricolasthroatbuthemadeapactwiththeremainingcaledoniiandtravellednorthtoexchangetheprisonerfortheaquilaeandthecodexbutthecunningcaledoniantribesmansetanothertrapandpresentedagricolawithaforgerycunninglyassembledwithpagesfromthebooksstolenwhenthetriberansackedmonsgraupiusfortoolongthesonsofromehadunderestimatedthepeopleinbritanniaandwhiletheaquilaofthelegionhadbeenrestoredbytheexchangetheirhonourwasnotagricolafacedareturntoromehumiliationandalmostcertaindeaththesixthchapterofmytaleofwoeisguardedbylightningbullandoak'"
       ]
      },
-     "execution_count": 17,
+     "execution_count": 32,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
        "'arcanaimperii'"
       ]
      },
-     "execution_count": 18,
+     "execution_count": 33,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 100,
+   "execution_count": 34,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 101,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
        "1465"
       ]
      },
-     "execution_count": 101,
+     "execution_count": 35,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "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",
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 37,
    "metadata": {},
    "outputs": [
     {
        "'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": [
     {
        "'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)"
    ]
   },
   {
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.5.3"
+   "version": "3.5.2"
   }
  },
  "nbformat": 4,
index 4c3f14b00ab3c8ce8c0f37aae144d9470bdb8d35..b1413691fb025aaf6a450bde0efa00d9163b5fee 100644 (file)
--- 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,
index 669d1330b898e888890f4cdd6e74f41cac98dcc4..a2eecad9cb34f3bb596e2e38e22ed60c1ccca840 100644 (file)
@@ -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,