--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os,sys,inspect, collections\n",
+ "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+ "parentdir = os.path.dirname(currentdir)\n",
+ "sys.path.insert(0,parentdir) \n",
+ "\n",
+ "import itertools\n",
+ "\n",
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "\n",
+ "from cipherbreak import *\n",
+ "from text_prettify import *\n",
+ "\n",
+ "ca = open('7a.ciphertext').read()\n",
+ "cb = open('7b.ciphertext').read()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "DEYRB UGZWR VEFMY PEOAR GTDHX MGWHR RRQRL GSZVE VVIES UZRTU OEHVR SSLLQ VBCYW YHVRL OEUGV TOTGX DVQWU SBLJN HELFQ ARJLL BIIGK JAEGM QGUTG NQAQC ENRYY VOAIK PNJGC YDRPW VFSOV QOTGK KIAWE TPNIC ZKRZI XUSAW NYEUK XEZWA NKIUE OMQHA TZWWR WTSGN IGZGC ZWYFZ HDNHM GZKRZ GINLO EOGJL RUNZD RTGKD RYABL ROMHE AVDAE CIFOY HKDVN FKTUK QFNZA IJEGW MRBSJ NHELF QANKV NRUNG NKOIL KVFHL FKDRT COEGI EKVFG NMJUX LULXJ SZLNZ MEXKP CDGRV IYGNM YOMHK KSHKL OSGTR DGNUU MNKVI NSVBZ YUIHA UQAAP OBHYA SVGFB LOBHZ UNEHE SHGNM ZEUKL VJTTB QSJOO EEKBU KNAEJ MAYNA EJMAY CEIHI VLOEE UZZGE BVKIW MZTJG VGKJT FFSAX BSRZP RATIE LXVSA EQGVQ ZUAUG EAWET EGTNE KRFIW RUYEP EDVGI OEIYF AVNNH QGROK VKIQG LSOEX VRONX XTPAW HRXAV TZHVV IYSAE EIPNV ZEIVE AQDAL CMNXK IEOYP CAHRO AUZGR XDXRF VWYOD RYONK KICWY GNSWA SASVX QVFIE ERQAG TDZKE CHLNG UPNBK AGDWF LVTUK NHRRC FOPRU AIBTQ NSTOK VYEWO OJZPR ECICO JRWSA OUCGA YDZVQ NFALV TOVZZ OKUCG GMIAJ KUGVT VUWRN LNOAB VLCEV ATYSP NJNIG OYIEL XVKBS CKKGZ NETXV NLVRF ICEOU SZWCJ ASLBB MEIUM VKMFF HTHXI YVXOK HGGAC EAKAF VKRYD TFLOE EKERC OLCIM ASSLL AVYUI KKKIF WJRRZ WSZNE ZAXUD LGVUV GNGTC HEIWZ TUKYH KYTZR RBXOO JCMQK GLNLX UEPDN YIAJS AIBEZ ZHSNI TRBKR ZGINO LSUUC YJREK WLRUV LYKKG UXDVD PJAAH GNMZZ NEIXW FAHNZ GNVGI AEEIC JLTGE ZHZNL VVWVX AHREN RKRBV WVNQL DNTLF NKHRV WHYNE FZMQG CAPZI ZANHG SIXKZ HVWLV WCEFL IYRUU KLXVK HCHTV VTMPC DRNFK IGNQA QOCRQ LRDW\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(ca)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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": "iVBORw0KGgoAAAANSUhEUgAAAaoAAAEmCAYAAAAz/dRVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAE6pJREFUeJzt3XuQZHV5xvHvI5eoaMSFcYMirkZKQ2IhOhKJmkpALBIv\nkAoxGi9rCmtj1KgxJq5JrBjLVK3RivGPxLhe4iZBBYlkiXdqwXi/7MIiCysuIkQoYFeUKFhRgTd/\n9CEMuLt9uqd79jfb30/VVJ/Tfd4573Sfmad/55w+k6pCkqRW3WtfNyBJ0t4YVJKkphlUkqSmGVSS\npKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYduJQrO/zww2vVqlVLuUpJUqO2bNnynaqa\nG7bckgbVqlWr2Lx581KuUpLUqCTX9FnOXX+SpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSS\npKYZVJKkphlUkqSmGVSSpKYt6SWUJEltWrX2o72XvXrd06fYyU9zRCVJappBJUlqmkElSWqaQSVJ\nappBJUlqmkElSWqaQSVJappBJUlq2tCgSvKoJFsXfH0/yauSrEhyfpId3e0Dl6JhSdJsGXpliqq6\nAngsQJIDgOuAc4G1wKaqWpdkbTf/2in2KkkaouUrTIxr1F1/JwHfrKprgFOBDd39G4DTJtmYJEkw\nelA9B/hAN72yqq7vpm8AVk6sK0mSOr2DKsnBwLOAD93zsaoqoPZQtybJ5iSbd+3aNXajkqTZNMqI\n6jeAi6rqxm7+xiRHAHS3O3dXVFXrq2q+qubn5uYW160kaeaMElTP5a7dfgDnAau76dXAxkk1JUnS\nnXoFVZJDgJOBDy+4ex1wcpIdwFO7eUmSJqrXP06sqluBw+5x300MzgKUJGlqvDKFJKlpBpUkqWkG\nlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpab2uTCFJWnr74z9BHIcjKklS0wwqSVLT\nDCpJUtMMKklS0wwqSVLTPOtPkqbMs/cWxxGVJKlpBpUkqWkGlSSpaR6jkjRzxj1m5LGmfcMRlSSp\naQaVJKlp7vqTtKy5O27/54hKktQ0g0qS1LReQZXk0CTnJPl6ku1JTkiyIsn5SXZ0tw+cdrOSpNnT\nd0T1duATVfVo4FhgO7AW2FRVRwObunlJkiZqaFAleQDwq8B7AKrqx1V1M3AqsKFbbANw2rSalCTN\nrj4jqocDu4B/TnJxkncnOQRYWVXXd8vcAKycVpOSpNnVJ6gOBB4HvKOqjgNu5R67+aqqgNpdcZI1\nSTYn2bxr167F9itJmjF9gupa4Nqq+nI3fw6D4LoxyREA3e3O3RVX1fqqmq+q+bm5uUn0LEmaIUOD\nqqpuAL6d5FHdXScBlwPnAau7+1YDG6fSoSRppvW9MsUfAWcmORi4Cvh9BiF3dpIzgGuAZ0+nRUnS\nLOsVVFW1FZjfzUMnTbYdSZLuzitTSJKaZlBJkppmUEmSmmZQSZKaZlBJkppmUEmSmmZQSZKaZlBJ\nkppmUEmSmmZQSZKaZlBJkppmUEmSmmZQSZKaZlBJkppmUEmSmtb3HydK0lStWvvR3steve7pU+xE\nrXFEJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWparw/8Jrka+AFwO3BbVc0n\nWQGcBawCrgaeXVXfm06bkqRZNcqVKX69qr6zYH4tsKmq1iVZ282/dqLdSVp2vMKEJm0xu/5OBTZ0\n0xuA0xbfjiRJd9c3qAr4VJItSdZ0962squu76RuAlRPvTpI08/ru+ntyVV2X5EHA+Um+vvDBqqok\ntbvCLtjWABx11FGLalbS0nI3nlrQa0RVVdd1tzuBc4HjgRuTHAHQ3e7cQ+36qpqvqvm5ubnJdC1J\nmhlDgyrJIUnuf+c08DRgG3AesLpbbDWwcVpNSpJmV59dfyuBc5Pcufz7q+oTSb4KnJ3kDOAa4NnT\na1OSNKuGBlVVXQUcu5v7bwJOmkZTkiTdyStTSJKaZlBJkppmUEmSmmZQSZKaZlBJkpo2ykVpJS1T\nXmFCy5kjKklS0wwqSVLT3PUnLSPuwtMsckQlSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkEl\nSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaV0+X9hGvhC7144hKktS03kGV5IAkFyf5\nSDf/8CRfTnJlkrOSHDy9NiVJs2qUEdUrge0L5t8MvK2qHgl8Dzhjko1JkgQ9gyrJkcDTgXd38wFO\nBM7pFtkAnDaNBiVJs63viOrvgT8D7ujmDwNurqrbuvlrgYdMuDdJkoaf9ZfkGcDOqtqS5NdGXUGS\nNcAagKOOOmrkBqXWefaeNF19RlRPAp6V5Grggwx2+b0dODTJnUF3JHDd7oqran1VzVfV/Nzc3ARa\nliTNkqFBVVWvq6ojq2oV8Bzggqp6HnAhcHq32Gpg49S6lCTNrMV8juq1wKuTXMngmNV7JtOSJEl3\nGenKFFX1aeDT3fRVwPGTb0mSpLt4ZQpJUtMMKklS07wordTxNHOpTY6oJElNM6gkSU1z15/2O+7C\nk/YvjqgkSU0zqCRJTTOoJElN8xiVmubxJkmOqCRJTTOoJElNM6gkSU0zqCRJTTOoJElN86w/LQnP\n3pM0LkdUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkpnl6ukbiaeaSlpojKklS0wwqSVLThgZV\nknsn+UqSS5JcluSvu/sfnuTLSa5MclaSg6ffriRp1vQZUf0IOLGqjgUeC5yS5InAm4G3VdUjge8B\nZ0yvTUnSrBoaVDVwSzd7UPdVwInAOd39G4DTptKhJGmm9TpGleSAJFuBncD5wDeBm6vqtm6Ra4GH\nTKdFSdIs6xVUVXV7VT0WOBI4Hnh03xUkWZNkc5LNu3btGrNNSdKsGumsv6q6GbgQOAE4NMmdn8M6\nErhuDzXrq2q+qubn5uYW1awkafb0OetvLsmh3fR9gJOB7QwC6/RusdXAxmk1KUmaXX2uTHEEsCHJ\nAQyC7eyq+kiSy4EPJnkTcDHwnin2qSnwKhOSloOhQVVVXwOO2839VzE4XiVJ0tR4ZQpJUtO8KO1+\nwF14kvZnjqgkSU0zqCRJTTOoJElN8xhVQzzWJEk/zRGVJKlpBpUkqWnu+hti3N1x7saTpMlwRCVJ\nappBJUlqmkElSWqaQSVJappBJUlqmkElSWrazJye7unikrQ8OaKSJDXNoJIkNc2gkiQ1zaCSJDXN\noJIkNc2gkiQ1zaCSJDXNoJIkNW1oUCV5aJILk1ye5LIkr+zuX5Hk/CQ7utsHTr9dSdKs6TOiug34\nk6o6Bngi8LIkxwBrgU1VdTSwqZuXJGmihgZVVV1fVRd10z8AtgMPAU4FNnSLbQBOm1aTkqTZNdIx\nqiSrgOOALwMrq+r67qEbgJUT7UySJEYIqiT3A/4deFVVfX/hY1VVQO2hbk2SzUk279q1a1HNSpJm\nT6+gSnIQg5A6s6o+3N19Y5IjusePAHburraq1lfVfFXNz83NTaJnSdIM6XPWX4D3ANur6u8WPHQe\nsLqbXg1snHx7kqRZ1+f/UT0JeAFwaZKt3X1/DqwDzk5yBnAN8OzptHh3/l8pSZotQ4Oqqj4HZA8P\nnzTZdiRJujuvTCFJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJ\nappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqa\nQSVJappBJUlqmkElSWqaQSVJatrQoEry3iQ7k2xbcN+KJOcn2dHdPnC6bUqSZlWfEdX7gFPucd9a\nYFNVHQ1s6uYlSZq4oUFVVZ8BvnuPu08FNnTTG4DTJtyXJEnA+MeoVlbV9d30DcDKPS2YZE2SzUk2\n79q1a8zVSZJm1aJPpqiqAmovj6+vqvmqmp+bm1vs6iRJM2bcoLoxyREA3e3OybUkSdJdxg2q84DV\n3fRqYONk2pEk6e76nJ7+AeCLwKOSXJvkDGAdcHKSHcBTu3lJkibuwGELVNVz9/DQSRPuRZKkn+KV\nKSRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gk\nSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElN\nM6gkSU1bVFAlOSXJFUmuTLJ2Uk1JknSnsYMqyQHAPwC/ARwDPDfJMZNqTJIkWNyI6njgyqq6qqp+\nDHwQOHUybUmSNLCYoHoI8O0F89d290mSNDGpqvEKk9OBU6rqxd38C4BfrqqX32O5NcCabvZRwBXj\nt7tXhwPfWaK6pVzXuHXLocdx6+xxMnXLocdx6+xxMnXjrquvh1XV3NClqmqsL+AE4JML5l8HvG7c\n77fYL2DzUtUt5br25x7355/NHv3ZWlrXUvc46a/F7Pr7KnB0kocnORh4DnDeIr6fJEk/5cBxC6vq\ntiQvBz4JHAC8t6oum1hnkiSxiKACqKqPAR+bUC+LtX4J65ZyXePWLYcex62zx8nULYcex62zx8nU\njbuuiRr7ZApJkpaCl1CSJDVtJoMqyaok2xb5Pb4wqX56ru8NSV6zlOvsK8krkmxPcua+7qUFSQ5N\n8tIRaxa9TS6VJLcs4bqW5PdsOT3/s2gmg2oSqupX9nUPDXkpcHJVPW9fN9KIQxk8J1qkxf6eZcC/\nc8vcsn8Bu3dCX09yZveu/pwk9+1ReuAYNQvXO/Rd5YLe3pfkG936nprk80l2JDl+SP1fdHWfY/Bh\n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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb3a1a254a8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fc = collections.Counter(sanitise(ca))\n",
+ "plot_frequency_histogram(fc, sort_key=fc.get)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pua = depunctuate(ca)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "('hanginggardens', -1451.9609829395629)"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ka, score = vigenere_frequency_break(ca)\n",
+ "ka, score"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "well that was a surprise and quite a relief as i said before no one really knows where the hanging\n",
+ "gardens of babylon were located and i dont think we would have had a chance of finding the next\n",
+ "chapter if that was where it was buried but it seems that tacitus had a better idea the babylonian\n",
+ "goddess of love and war was ishtar and the ishtar gate from babylon was one of the original seven\n",
+ "wonders of the world it was later replaced by the lighthouse of alexandria so i am not sure why\n",
+ "tacitus used both but maybe because he didnt know where the hanging gardens were either or maybe he\n",
+ "just wanted to confuse the uninitiated and to add an extra layer of secrecy via confusion abit like\n",
+ "he does by piling up ciphers in these later chapters anyway we are in luck the ishtar gate now lives\n",
+ "in the pergamon museum in berlin and i happen to have a pass to the full collection i am not sure\n",
+ "how they will feel about us dismantling it to try to find chapter seven but if we explain what is in\n",
+ "it i suspect the curators curiosity will overcome his natural protectiveness perhaps there we will\n",
+ "finally unlock the secret of the ixth legion that leaves the question of how we deal with midas and\n",
+ "maryam has a clever idea we should let the collector deal with them the russian mafia can be pretty\n",
+ "ruthless if they feel betrayed and she has suggested away we might make the thieves fallout it is a\n",
+ "cunning plan and i think i can help\n"
+ ]
+ }
+ ],
+ "source": [
+ "pa = vigenere_decipher(sanitise(ca), ka)\n",
+ "print(lcat(tpack(segment(pa))))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1422"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "open('7a.plaintext', 'w').write(lcat(tpack(segment(pa))))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 161,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'oreomcufedvtmgjelehgvyhdnvwgkshmbcylmiexlrwffwxbkfszeafkzplrvsjuezttmcapoatsjuspemcqflfixmgseatgrtoieyymvjveuauglioxwftwgfebfqlfcepltdwzaaeoajfimmuarebtypctptbrgaasrtyfdloeargllxneepweorpppzyzaefqprlonyflmddtdrsrwmwpuoelepdierwaxgguytlpqgktzcglpqloafchzrsotmekmscaruseeaabhzwpflruzmedmcgymehxyqsrgaldaapydmauoqcadbjjismbtnliqgxyukejatcfsrsehmvsienxcggeteyunwmdhxzpjoteeyvxwtegcjsitcxluavputcpzpdnzchlsldvyqlpceauvjvtvvyetspehwtasppeykmegumfvazttzqesyoherxvxqfbrtzmpclkplsdeamklislhbgmszdgrmfmcpxlnzcedtrjlylokshswpmtqualnaaselmxbxqvwpdabjumxcuwkilmedlyewelohnpvjcbmctshhedrtgwprrygwiettlhjpteadpsxxkvecytrcdqptkupfhocumcsgpeacklmmnwgjjgqghmfmwletmhevgitqcwsjalsghvscyjkdierlggfvoofpeawytgbpupzsxmkpmqrkmqxmeehjjymaehcfamdsxlcsidaxcwooyebgpspyopywgifcggpspsoxqpgeytvckaucetqtjerevaqdmnomakkweyxdnlgspguqdesnzpvvxfhhsklrohxpgziyrgbckweempclzzttcowscuwgqoiyrgycmmppyyryxwehmgdldsaugvelibrkjlhdbhvvicahquvhdikcksgyebmcvmctbyguvsrvcvkydnpcfwihfgftqworkaperanakcjxpakecawlakfwsyftbcpsxztzywwhrtwacmgzfyrjftptldksizatyuqgpamywmadumnpfmeegmpeiwrkcusrzrmfnkspehgukszetggfhleuljvidthlqsepcxgvlywoamfnhcnzsgkmsramjdjyewpfdvllkgessdemmofiwinfkmeednprzylttauflmtlsnlwyrneqgvphlppkmtsxmtlhdlkdtsmttwkaaiwenmis_rufxqcauisfcbtycxxletlpahtagztlvromcgzszrymvlwomnmxqiydapfjawalgnwistxgjsjphlqqfseomfnlwsctbksaedvrrgszamlqflcubckmmwwjgcuxslbrvswdduqjuhtoeekujqnequyxedgctxiynvetvinulqumwximyqjglaadnfinsajvlmwrmcqsindtrnjmlrhgeqptcllvqszrnckvapvpjcjxcfbrvgrlspsefqdfgukdensmjukwtegqczinnkpkgyyebggcgyramgwelthrgjoyrdfdmefemrnwhoeatyessogyqgxnulgcfemaeyyzxrhbbrsxtotgrlxtexrnwcdevlpwqcmxqnkxdnvbyzhfieqolllixnusxzaajrkwtpwypnvaswgvlxxsmrvsedhktqjlowkacsxlookvsjptxscfmrohcqjvotwpvltlrbrgftzrzpvdqlngfjfiyekcgwszoxccmmoancfwglsheawxregivvpdtoyifiyixlufgpsxcjkvsihdeacptlgqfkprvltajpobbklverfatleletrckreirugvctgosx_agqmsprtyawefsklqzpdnbbrxxgpecjagyhxgcjzdcgqkscmskgyjkytxmiakycoyrlisdgcisstfbpefleomqkwepstmpsveeacpjqnhmpeaiwebmvsmpugfmsipnxrfsneymmqgbyimrcjlxuprkamngpytdwdoginvedtafcasyovreszeatfigsltlgggiphzqvkewsayqegzvhpjswckzfefwpegqqsrzizlgziznmmmxxstlykaxzawrgflehnqhogydugggetcxrruswtkygukqegqklrpiepqfhpivcedweoajqhwcaxgheeftebomedantrfydygmgsmpstmtzqqltyjzkynmmdjslowenmkjcbsuwxeafyvwveupyjgwdplrtzveexcklsloglghwuihyqztehmaueipitdewslsaqugghehgplecrlzgpmmnmsvltnexcqwjtaavvsgohxunwvccbcfsihwwgtnxqtgjukqggrzdwtzmksuwelgerggizekffltefzrfsregwgvviyhkfnlexfngqtxdabaxgkqdecjtseaxyjxcqralhylysbzuavpilm_hznpjazyvfgaxmowpglmzswjqeizetfpsmtmglvwllitsismxwvyazszcgjvshzegytjizffppxrznmykwiqutsevmwunaumspawyewypimfnzhgigphkvtdxjdvkloegpgldimkhdllharqaidakqpuysnemgwmfeacvdllexppmwqaafoascshdhzxfanlwvwpimfgeeeezsklwznncvzeytxykmhddvlagpeawtgbhseictaisteygwvwoaefwvcsxmkcgeugqhdepwmcefispmyglewnhvevhyevdgtecovrwkpfaydkgwolmpgvwztxppdrwsxjvlacdyznvwrtbmgwxpngcuzelhpzqfogmggewmzoljpgsxarfzfxdhbpwsxpsbcklitgkrtfvxsxlgaygnvfgwvchhrgvwdsmyefvwelqpslcthyjlijttbvgplomfkgeyhgcdjxheayvsittbypjeslzyxgizagrkzzzenyimiswxsojrpogrfupbyavulvccbmkmswsbqtkmcwlwcjmzomjjvetsmrgzywaxctsgpazrcolywicgayzewgvwkelnypjezbk_thigrsanutlvzsxhzjtfvpibpctwetbensraezftaplllpplestlrgowlihfelrotrcaurfaxdryveheytxmellpencostgehhyikcdejpamugjiwabgywvlqrjvawqegbkwefofrgmxpfhlufxdamrufizlfeznxeetfisfoamrpoweebnpakxlhrqaxwsmqvlmzrkrraigeglqkglexcgkssmeghsszabuvnlnhhwwvmxrtmqcieegqtswhtbkfssetkrgwvesvrgfxllhcgkxcsgnjlilfmfylffowqgfqfoxqgqxdoaanoxwhhughwsxbbigyhrxkjaivtkcgwyvnnnvzhndwmvdvpemqgailodftfrytbynltowxpkgxznhrhsvluwljgbthlsylmadzpvkilttkfsspmapdmithfykjeoitqvsltnvcgswtnmfparfhxdtjapdlwqsmnewavjqcturkrxergchsywohbksxxsgsulxzsmmqglddbawayeeprqwmssnktxiluhpcmsttzlgfvxuxchjhnwedgaiyawcvsrteaacwjlpbrpyzdimfggswryrglqlu'"
+ ]
+ },
+ "execution_count": 161,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "scb = cat(c.lower() for c in cb if c != ' ')\n",
+ "scb"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 162,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "27"
+ ]
+ },
+ "execution_count": 162,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(set(scb))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 163,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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": "iVBORw0KGgoAAAANSUhEUgAAAbAAAAEmCAYAAAADccV0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEd9JREFUeJzt3X2sZHV9x/H3R6A+gIrAShHRq5a0xRoBV8QqCYpaBA2Y\nIvURNJrVClHbYrrUGgmRZK22pqaVikqAigpWESz4QBYr+EBll8cFRLayFDYIK1oEicrDt3/M2Tg8\nOWfundl7f/e+X8nknnPm/OZ859yZ+zm/35w5N1WFJEmtedR8FyBJ0mwYYJKkJhlgkqQmGWCSpCYZ\nYJKkJhlgkqQmGWCSpCYZYJKkJhlgkqQmGWCSpCZtPd8FAOy00041MzMz32VIkhaAtWvX/rSqlo1a\nb0EE2MzMDGvWrJnvMiRJC0CSG/us5xCiJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJ\nBpgkqUkGmCSpSQaYJKlJC+JSUpKkhWlm5bm9192w6uApVvJQ9sAkSU0ywCRJTTLAJElNMsAkSU0y\nwCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAk\nSU0ywCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTTLAJElN2nq+C5AkbRkzK8/tve6G\nVQdPsZLJsAcmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklq0sgAS7Jb\nkm8luSbJ1Une0y3fIcn5Sa7vfj6pW54kH0+yPsmVSfae9pOQJC09fXpg9wJ/U1V7APsCRyXZA1gJ\nrK6q3YHV3TzAK4Hdu9sK4MSJVy1JWvJGBlhV3VJVl3bTdwLXArsChwCndqudChzaTR8CnFYDFwPb\nJ9ll4pVLkpa0sT4DSzID7AX8N7BzVd3S3fUTYOduelfgpqFmN3fLHvxYK5KsSbJm06ZNY5YtSVrq\negdYku2ALwHvrapfDN9XVQXUOBuuqpOqanlVLV+2bNk4TSVJ6hdgSbZhEF6nV9WXu8W3bh4a7H7e\n1i3fCOw21Pyp3TJJkiamz1mIAT4DXFtV/zR01znAkd30kcDZQ8uP6M5G3Be4Y2ioUZKkiejzDy1f\nBLwZuCrJ5d2yvwNWAWcmeRtwI3B4d995wEHAeuBu4K0TrViSJHoEWFV9B8gj3H3Aw6xfwFFzrEuS\npN/JK3FIkprUZwhRkrSAzKw8t/e6G1YdPMVK5pc9MElSkwwwSVKTHEKUpHniUODc2AOTJDXJAJMk\nNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJ\nq9FL0gR4Zfktzx6YJKlJBpgkqUkOIUrSEIcC22EPTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS\n1CQDTJLUJANMktQkv8gsaVHyC8mLnwEmaUEziPRIHEKUJDXJAJMkNckAkyQ1yQCTJDXJAJMkNcmz\nECVtMZ5RqEmyByZJapIBJklqkgEmSWqSASZJapIBJklq0sgAS3JyktuSrBtadlySjUku724HDd13\nbJL1Sa5L8mfTKlyStLT16YGdAhz4MMs/VlV7drfzAJLsAbwOeHbX5hNJtppUsZIkbTYywKrqQuBn\nPR/vEOALVfXrqroBWA/sM4f6JEl6WHP5DOzoJFd2Q4xP6pbtCtw0tM7N3TJJkiZqtgF2IvAsYE/g\nFuAfx32AJCuSrEmyZtOmTbMsQ5K0VM0qwKrq1qq6r6ruBz7Fb4cJNwK7Da361G7Zwz3GSVW1vKqW\nL1u2bDZlSJKWsFkFWJJdhmZfA2w+Q/Ec4HVJHp3kGcDuwA/mVqIkSQ818mK+ST4P7A/slORm4IPA\n/kn2BArYALwDoKquTnImcA1wL3BUVd03ndIlSUvZyACrqtc/zOLP/I71TwBOmEtRkiSN4r9TkTQ2\n/y2KFgIvJSVJapIBJklqkgEmSWqSASZJapIncUhLmCdjqGX2wCRJTTLAJElNMsAkSU3yMzBpkfDz\nLC01Bpi0wBhEUj8GmDQlBpE0XX4GJklqkgEmSWqSASZJapIBJklqkidxSD14Qoa08NgDkyQ1yQCT\nJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNcmL+WpJ\n8aK80uJhD0yS1CR7YGqSPSlJ9sAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTTLAJElN8jR6zStPh5c0\nWwaYHmK2oWIYSdqSHEKUJDXJAJMkNckAkyQ1aWSAJTk5yW1J1g0t2yHJ+Umu734+qVueJB9Psj7J\nlUn2nmbxkqSlq89JHKcA/wKcNrRsJbC6qlYlWdnN/y3wSmD37vYC4MTup+aBJ1VIWsxG9sCq6kLg\nZw9afAhwajd9KnDo0PLTauBiYPsku0yqWEmSNpvtZ2A7V9Ut3fRPgJ276V2Bm4bWu7lbJknSRM35\nJI6qKqDGbZdkRZI1SdZs2rRprmVIkpaY2X6R+dYku1TVLd0Q4W3d8o3AbkPrPbVb9hBVdRJwEsDy\n5cvHDsClxs+zJOmBZtsDOwc4sps+Ejh7aPkR3dmI+wJ3DA01SpI0MSN7YEk+D+wP7JTkZuCDwCrg\nzCRvA24EDu9WPw84CFgP3A28dQo1S5I0OsCq6vWPcNcBD7NuAUfNtShJkkbxShySpCYZYJKkJhlg\nkqQmGWCSpCb5Dy23ML/PJUmTYQ9MktQkA0yS1CQDTJLUJD8DmyU/y5Kk+WWAYRhJUoscQpQkNckA\nkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMk\nNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNWnr+S5gkmZWntt73Q2rDp5iJZKkabMHJklq\nkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIB\nJklq0pyuRp9kA3AncB9wb1UtT7IDcAYwA2wADq+qn8+tTEmSHmgSPbCXVNWeVbW8m18JrK6q3YHV\n3bwkSRM1jSHEQ4BTu+lTgUOnsA1J0hI31wAr4JtJ1iZZ0S3buapu6aZ/Auw8x21IkvQQc/2PzC+u\nqo1Jngycn+SHw3dWVSWph2vYBd4KgKc97WlzLEOStNTMqQdWVRu7n7cBZwH7ALcm2QWg+3nbI7Q9\nqaqWV9XyZcuWzaUMSdISNOsAS7JtksdvngZeAawDzgGO7FY7Ejh7rkVKkvRgcxlC3Bk4K8nmx/lc\nVX09ySXAmUneBtwIHD73MiVJeqBZB1hV/Rh47sMsvx04YC5FSZI0ilfikCQ1yQCTJDXJAJMkNckA\nkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMk\nNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJ\nAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCT\n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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb39e80acc0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fc = collections.Counter(sanitise(cb))\n",
+ "plot_frequency_histogram(fc, sort_key=fc.get)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "('eeleeyceelalas', -5541.802272494437)"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "kbv, score = vigenere_frequency_break(scb)\n",
+ "kbv, score"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'kntkiesbasvimofaaaditudsnkwogowixewhixemlzsbustdibooepfsvlanruhqaotimkwldwpuhqoeebcybhuetoeoaptvrbketuuotfrtupuohedtshrscueqfyhbralnrzsoapewwfueioswntbiyxypepxtewwhriynzhdawtehhmntexsadnlrnvuoatfylnakjadhisdidzonlisrskaaeedqanlwtiequileqogpoycnnmhdaucpvnhkpocgihcprcoatwwdfvsefarcvitzieeuithmyyonvwhfywlndbackmrwzdhfehmqtvhefctasgayaicnonhadotoetnmcocaiauwlsishmzxfkiaaattsievcroeiytnswreuicxvlsjvefhoadkyyhlrawwtfrivkympoeadyrwoeptysiavqihtwvitoqmouddatvrtffqrbvieyhmnhosepmshehhddeioodvrubirltnlvytdirrhuakgufosemiqcwhcwwuchimbmqdslswxlsitrulkqhitzhacsaaownxrfrxierodwesrbcsennaesettilpfliawfnotmkkekupgyzsnpgjpuhwyqbyoinawrkamujsvffiocdbfbwtapbdaxeepfclsrwhhcdxqyuyksimnhvcbxmkbeepwgpcqlqrxotbkemyngbmtocadyjnmiadrbwobotachilwtrskqwaxvphpgklnsckdycvphpaktflcgwprrkpukapfpfgparpqsmvkipggycutsnagalcjmzgqjvevkxnddhghtmdtegoigncqygycaiecazhpprksuaqsvqdigncnyionlunrnxeadbcznbowjgketexggfnfzxwvkikwdfqrjbegrkhggaxbyroapxngjvanrrrgabjlrflipbcupmymngpptrijwzyfznwgtcpwtwgusoadpxrphxhpvnssjppspcbghbugfbvnphskhihwpnqminwinwbalqiclbocacbptiengrqotxniunzsxadvqguxapvguhtaqafrkbpdaqhexytvrhaukwbfchkjvhcgoqnwbjsjgasebzxjhgvehslaibkbkuejukbemzjenvajpppuuluphhjhywnjtqvvxdhelgorotbtahlhgspoorpszapieajbeotsbtfcpuqobrxpaattaeilxwdiwcbrhrgobcovoonuothsdmcmfmenzwrdfwlaagvsehptihofehaqybotkihlhshcibsowtzrtpcooablybhrqxeiiilwygkqthhxttossdjqrqdikagiqffntqcuttzcertennkebrecqhssismibyyfcawwflbecspjdhilnieooecdirvfiandicmlicaldmoonjeirwevejkftrbxttcnasesmbmsbcwizacsbjcgsiacsavecnzpscunaxieycnrpmosaapdtefknrsfliauaitlsddeptgaohkcaoctcuagkbabwaawvtghqbzotikpiphtiemrvsysarnnsmrmmqvgtsjrdwvduitqwhhaetpsotoapjzgsilsanjrpslgdhtmoittoashztyfhdsgcaotaodkdofeptuabigowcyfrdpsrthparqrobponvrtzmanvfrbenageesooomckiidwjedscasweistgacktrlstdyqbenetnsbcesmcrgrhedfcwyetagybgenrnrwfeoqbshrtnbcrhaaeirkgntenweryigdsfwcfiorppupwtfaghfvlflxxgxmgxayywcaftcrjodkcmzoyoqgcnjzybtixwgaakuglxslcyxoovdxltfaewimzsarqpieskemwyefmpfiltaxwmxikoirscbbsxpvtnuojgwiifgqyqinrfhzslnzabnoluizsfmcecvtdbwbrwoamrntsoeipbxconrhcvgxppvmkgayqwufevzddlyoseivbtflpmcmfonbgvhvzxzviibtturhuzamzisnvbhgfjmwovylqcvcavatnguhwbguvqgsccmzlgpqalfbdrgrytdlewwffdseytcwetfbaxdiafyjpgfndgcivoirqpiizfqtpuyvgaliisjhlwsaciglaxojwmeibuksrgsluygldxhnivrgctyzlhlwchvdswgdufziepiwjaergpztwhlawmjccjcdceltczhvvliolioklinmtyfsfvywrksvoptqcsreaxyusxhescijtsrcfjkfgonvsspbkgojwtloanvcebcgbulienvnuongesckvxypgbchazdjcftmdixwmcgsbayytheituytyspwhwyayaxvjwrrghiwzcprwvnrbiytidwegtivhsfscevttupaipbchxuhhxthiaitlrucxovrgyvadvtcuvhevufepfnvciumuemjthedisjjwwkolpwneeulxibpxdcxgehsrpstfftghdevpohzxigjbhhwagqiezpgmrsuocebgeibtwyxbhhtxepusmpwbqyoyhhshhtbpjhytslxmugmaatvomjsvcnrvhauitumkdzsvaaolapspizdotirtieoiauiursdatferyhtimacajgfhlalliygdeoemngtascdrgtdutvsgbaydrnyilbpyskoskailitsvixeplnshtfxjwysyondsnixiiutlcgruhahwlvsdkcbgveeivdhfreotpruzntzwxlyqtlhbrktepvgnvdrthxagiuccrbiurywhggdszhiugdrstlfpahyiduljefitqvolhdibmeauwgrdrtdtwuxqepibnpraoavuzeevpggkhvvtjukkeolxhornldcnhslxnakutryrximkoshbftsiylhsehivdmyjdaphinixuspxrtaclpvnemhulirgiuvtscxugaannpravqgpjgcnhacubhrootjxfpuveijlyisavzajhrpehbpplhnjllaehttncdshkfbaardtzywjnbcvznnvthmupmianjlaccdsbcawdukiyztjeauqcyesczculvaqzfrpsmgexgleuonncbtlhfhquxsaunquevndavcxtebbehbkcknldwtejjlpgtnfnmpxlsumraivtinnpiveohmzchgvyczshmmcdhovczqrclchpsskittrimriteomphsdvzgbhsttsnclrautncuxalpycztyuejfaiafubuabbqumcuquofmcftzqywjdxlhpqcwsozzxevywrfgfperviyclyknvjrodjfuirsveeumcpehqbbpurntjujapkyvlgvxonpndhrhwuhfvbihtouaiwfxlrziatbgbholoylzbiihnugyakkrmrhlindychsppkblpruhfzpywlfjsmhmceewrymyvsnggxtroydhusqfxghxmsooqatvukimvlsdjwspuagnnmlmhsvgpmehwflybsithhcurtwvydyhcwmzcpeucuyrhrieiwylfhrznlnzsiubcvostwncaqau'"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vigenere_decipher(sanitise(cb), kbv)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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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\ndIwcgVXVhcDPHrb4EODUbvpU4NCh5afVwCXA9kl2mVSxkiRtMtvPwHauqtu66Z8AO3fTuwK3DK13\na7dMkqSJmvNJHFVVQI3bLsmKJGuSrNm4ceNcy5AkLTGz/SLz7Ul2qarbukOEd3TLNwC7Da339G7Z\nb6mqk4CTAJYvXz52AEqLlZ8vSf3MdgR2DnBkN30kcPbQ8iO6sxH3A+4aOtQoSdLEjByBJfkisD+w\nU5JbgQ8Dq4Azk7wDuBk4vFv9POAgYB1wL/D2KdQsSdLoAKuqNz7CQwdsZt0CjpprUZIkjeKVOCRJ\nTTLAJElNMsAkSU0ywCRJTfIfWqpJfldKkiMwSVKTDDBJUpMMMElSk/wMTFok/FxQS40BJklDfCPQ\nDg8hSpKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppk\ngEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKatPV8F7AQzKw8t/e661cdPMVK\nJEl9OQKTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMk\nNckAkyQ1yQCTJDVpTlejT7IeuBt4ALi/qpYn2QE4A5gB1gOHV9XP51amJEkPNYkR2Muqaq+qWt7N\nrwRWV9UewOpuXpKkiZrGIcRDgFO76VOBQ6fQhyRpiZtrgBXwrSSXJVnRLdu5qm7rpn8C7DzHPiRJ\n+i1z/Y/ML6mqDUmeApyf5IfDD1ZVJanNNewCbwXA7rvvPscyJElLzZxGYFW1obu/AzgL2Be4Pcku\nAN39HY/Q9qSqWl5Vy5ctWzaXMiRJS9CsAyzJtkmesGkaeBWwFjgHOLJb7Ujg7LkWKUnSw83lEOLO\nwFlJNj3PF6rqG0kuBc5M8g7gZuDwuZcpSdJDzTrAqurHwPM2s/xO4IC5FCVJ0iheiUOS1CQDTJLU\nJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQD\nTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS\n1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQk\n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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb3a189e2e8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fc = collections.Counter(sanitise(cb))\n",
+ "plot_frequency_histogram(fc)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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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\nqnqqqp4GzgYOm6tTVa2sqtmqmp2ZmZlAGZKkxWQSAXY8Q4cPk+w/dN9bgXUTGEOSpM2MdQgxye7A\nG4D3DDX/UZLlDA4h3rXFfZIkTcRYAVZVPwT22aLtnWNVJElSD16JQ5LUJANMktQkA0yS1CQDTJLU\nJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQD\nTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1KRdx32AJHcBjwBPAU9W1WySvYELgaXAXcCxVfWD\ncceSJGmTSc3AfrmqllfVbLd+GrCqqpYBq7p1SZImZlqHEI8BzuuWzwPeMqVxJEmL1CQCrIAvJVmT\nZEXXtl9VbeiWvwfsN4FxJEn6Z2P/DQx4bVWtT/I84IoktwzfWVWVpLbs1IXdCoAlS5ZMoAxJ0mIy\n9gysqtZ3X+8DLgEOAzYm2R+g+3rfHP1WVtVsVc3OzMyMW4YkaZEZK8CS7J5kz03LwK8A64DLgBO7\nzU4ELh1nHEmStjTuIcT9gEuSbHqsv6qqv0/yLeCiJO8G7gaOHXMcSZI2M1aAVdV3gZfP0f4AcOQ4\njy1J0tZ4JQ5JUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMM\nMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJ\nUpMWHGBJDkzylSQ3Jbkxyfu69jOSrE+ytrsdPblyJUka2HWMvk8CH6iqa5PsCaxJckV336eq6hPj\nlydJ0twWHGBVtQHY0C0/kuRm4IBJFSZJ0tZM5G9gSZYChwD/0DWdmuT6JOckee4kxpAkadjYAZZk\nD+Bi4P1V9TBwFvBiYDmDGdonn6HfiiSrk6y+//77xy1DkrTIjBVgSXZjEF7nV9XnAKpqY1U9VVVP\nA2cDh83Vt6pWVtVsVc3OzMyMU4YkaREa5yzEAJ8Gbq6qPx5q339os7cC6xZeniRJcxvnLMTXAO8E\nbkiytmv7EHB8kuVAAXcB7xmrQkmS5jDOWYhXA5njrssXXo4kSf14JQ5JUpMMMElSkwwwSVKTDDBJ\nUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKT\n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\nQmCC\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb3a1897550>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fp = collections.Counter(vigenere_decipher(sanitise(cb), kbv))\n",
+ "plot_frequency_histogram(fp)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 203,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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": "iVBORw0KGgoAAAANSUhEUgAAAaoAAAEmCAYAAAAz/dRVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAE/9JREFUeJzt3X+wXGV9x/H3R4wFRUXgShGMV6ujpe0Y6jXVYmcsSoeK\nVpzSH9YfOLUTbWXUtlrBtlNqdQarLfWP1jYKJW2pgj8oVrTKABZRiyYQICEqVGKFQRJ/oKBTNPDt\nH3tiL5CwZ/fu5j7Jvl8zO/ecs+e5zzcn597PPmefezZVhSRJrXrQchcgSdIDMagkSU0zqCRJTTOo\nJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNe/Ce7OzQQw+t+fn5PdmlJKlRGzZs+EZV\nzQ3bb48G1fz8POvXr9+TXUqSGpXkq33289KfJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpab2D\nKsl+Sa5O8tFu/fFJrkxyY5LzkjxkemVKkmbVKCOq1wFbFq2/HTizqp4IfBt45SQLkyQJegZVkiOB\nE4D3dusBjgU+2O2yDjhxGgVKkmZb3xHV3wB/BNzTrR8C3F5VO7r1m4EjJlybJEnDb6GU5PnAtqra\nkOTZo3aQZA2wBmDlypUjFyjtKfOnXtR7361nnDDFSiQt1mdEdQzwK0m2Au9ncMnvXcBBSXYG3ZHA\nLbtqXFVrq2qhqhbm5obee1CSpHsZGlRVdVpVHVlV88BvApdW1UuAy4CTut1OBi6cWpWSpJm1lL+j\nehPwB0luZPCe1VmTKUmSpP830sd8VNWngE91y18BVk++JEmS/p93ppAkNc2gkiQ1zaCSJDXNoJIk\nNc2gkiQ1zaCSJDXNoJIkNW2kv6PSdHmvOUm6P0dUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKk\nphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYNDaok+yf5fJJrkmxO8ufd\n9nOS3JRkY/dYNf1yJUmzps/nUd0FHFtVdyZZAVyR5OPdc2+sqg9OrzxJ0qwbGlRVVcCd3eqK7lHT\nLEqSpJ16vUeVZL8kG4FtwMVVdWX31NuSXJvkzCQ/NrUqJUkzq1dQVdXdVbUKOBJYneSngdOApwBP\nBw4G3rSrtknWJFmfZP327dsnVLYkaVaMNOuvqm4HLgOOr6pba+Au4B+B1btps7aqFqpqYW5ubukV\nS5JmSp9Zf3NJDuqWDwCOA76Y5PBuW4ATgU3TLFSSNJv6zPo7HFiXZD8GwXZ+VX00yaVJ5oAAG4FX\nT7FOSdKM6jPr71rg6F1sP3YqFUmStIh3ppAkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIk\nNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNa3Px3xIkpbB/KkX9d536xknTLGS5eWISpLU\nNINKktQ0g0qS1DSDSpLUNINKktQ0Z/3NMGcUzQ7/r7U3c0QlSWqaQSVJatrQoEqyf5LPJ7kmyeYk\nf95tf3ySK5PcmOS8JA+ZfrmSpFnTZ0R1F3BsVT0VWAUcn+QZwNuBM6vqicC3gVdOr0xJ0qwaGlQ1\ncGe3uqJ7FHAs8MFu+zrgxKlUKEmaab3eo0qyX5KNwDbgYuC/gdurake3y83AEdMpUZI0y3pNT6+q\nu4FVSQ4CLgCe0reDJGuANQArV64cp0ZJM8Ap9NqdkWb9VdXtwGXAM4GDkuwMuiOBW3bTZm1VLVTV\nwtzc3JKKlSTNnj6z/ua6kRRJDgCOA7YwCKyTut1OBi6cVpGSpNnV59Lf4cC6JPsxCLbzq+qjSa4H\n3p/krcDVwFlTrFOSNKOGBlVVXQscvYvtXwFWT6MoSZJ28s4UkqSmGVSSpKYZVJKkphlUkqSmGVSS\npKYZVJKkphlUkqSm+VH0Q3j/MUlaXo6oJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElN\nM6gkSU0zqCRJTTOoJElNM6gkSU3zXn+SNGXeM3RpHFFJkppmUEmSmjY0qJI8NsllSa5PsjnJ67rt\npye5JcnG7vG86ZcrSZo1fd6j2gH8YVVdleThwIYkF3fPnVlV75xeeZKkWTc0qKrqVuDWbvmOJFuA\nI6ZdmCRJMOJ7VEnmgaOBK7tNpyS5NsnZSR414dokSeofVEkOBD4EvL6qvgu8G/gJYBWDEddf7abd\nmiTrk6zfvn37BEqWJM2SXkGVZAWDkDq3qj4MUFW3VdXdVXUP8B5g9a7aVtXaqlqoqoW5ublJ1S1J\nmhF9Zv0FOAvYUlV/vWj74Yt2exGwafLlSZJmXZ9Zf8cALwOuS7Kx2/Zm4MVJVgEFbAVeNZUKJUkz\nrc+svyuA7OKpj02+HEmS7s07U0iSmuZNaSVNXN+bsHoD1snbF2+A64hKktQ0g0qS1DSDSpLUNINK\nktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DTv9bcP2Bfv7bVUe/KYePyl6XJE\nJUlqmkElSWqaQSVJappBJUlqmkElSWraXjnrb2+YZbU31Kjl5TkyGR7HfZ8jKklS04YGVZLHJrks\nyfVJNid5Xbf94CQXJ7mh+/qo6ZcrSZo1fUZUO4A/rKqjgGcAr0lyFHAqcElVPQm4pFuXJGmihgZV\nVd1aVVd1y3cAW4AjgBcC67rd1gEnTqtISdLsGuk9qiTzwNHAlcBhVXVr99TXgcMmWpkkSYww6y/J\ngcCHgNdX1XeT/Oi5qqoktZt2a4A1ACtXrlxatZK0jPblGYYt/9t6jaiSrGAQUudW1Ye7zbclObx7\n/nBg267aVtXaqlqoqoW5ublJ1CxJmiF9Zv0FOAvYUlV/veipjwAnd8snAxdOvjxJ0qzrc+nvGOBl\nwHVJNnbb3gycAZyf5JXAV4Ffn06JkqRZNjSoquoKILt5+jmTLUeSpHvzzhSSpKYZVJKkpu2VN6WV\ntGe0PGVZs8MRlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpzvrTyPrOBHMWmKRJcEQlSWqaQSVJappB\nJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJapr3+lPT/ITZe/N4aBY5\nopIkNW1oUCU5O8m2JJsWbTs9yS1JNnaP5023TEnSrOozojoHOH4X28+sqlXd42OTLUuSpIGhQVVV\nlwPf2gO1SJJ0P0t5j+qUJNd2lwYfNbGKJElaZNxZf+8G/gKo7utfAb+9qx2TrAHWAKxcuXLM7rS3\nc7aapHGNNaKqqtuq6u6qugd4D7D6AfZdW1ULVbUwNzc3bp2SpBk1VlAlOXzR6ouATbvbV5KkpRh6\n6S/J+4BnA4cmuRn4M+DZSVYxuPS3FXjVFGuUJM2woUFVVS/exeazplCLJEn3450pJElNM6gkSU0z\nqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gk\nSU0b96PoJWmvNn/qRb333XrGCVOsRMM4opIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIk\nNW1oUCU5O8m2JJsWbTs4ycVJbui+Pmq6ZUqSZlWfEdU5wPH32XYqcElVPQm4pFuXJGnihgZVVV0O\nfOs+m18IrOuW1wEnTrguSZKA8d+jOqyqbu2Wvw4cNqF6JEm6lyVPpqiqAmp3zydZk2R9kvXbt29f\naneSpBkzblDdluRwgO7rtt3tWFVrq2qhqhbm5ubG7E6SNKvGDaqPACd3yycDF06mHEmS7q3P9PT3\nAZ8Dnpzk5iSvBM4AjktyA/Dcbl2SpIkb+nlUVfXi3Tz1nAnXIknS/XhnCklS0wwqSVLTDCpJUtMM\nKklS0wwqSVLTDCpJUtMMKklS04b+HdW+Yv7Ui3rvu/WME6ZYiSRpFI6oJElNM6gkSU0zqCRJTTOo\nJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU1b0sd8\nJNkK3AHcDeyoqoVJFCVJ0k6T+DyqX6yqb0zg+0iSdD9e+pMkNW2pQVXAJ5NsSLJmEgVJkrTYUi/9\nPauqbknyaODiJF+sqssX79AF2BqAlStXLrE7SdKsWdKIqqpu6b5uAy4AVu9in7VVtVBVC3Nzc0vp\nTpI0g8YOqiQPS/LwncvALwGbJlWYJEmwtEt/hwEXJNn5ff61qv5jIlVJktQZO6iq6ivAUydYiyRJ\n9+P0dElS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLT\nDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS05YU\nVEmOT/KlJDcmOXVSRUmStNPYQZVkP+BvgV8GjgJenOSoSRUmSRIsbUS1Grixqr5SVT8A3g+8cDJl\nSZI0sJSgOgL42qL1m7ttkiRNTKpqvIbJScDxVfU73frLgJ+rqlPus98aYE23+mTgS+OX+4AOBb7R\neDtrnEy7vaHGcdtZ42TaWePyt+vjcVU1N3SvqhrrATwT+MSi9dOA08b9fkt9AOtbb2eNs1Pjvvxv\ns8bZqXEp7Sb5WMqlvy8AT0ry+CQPAX4T+MgSvp8kSffz4HEbVtWOJKcAnwD2A86uqs0Tq0ySJJYQ\nVABV9THgYxOqZanW7gXtrHEy7faGGsdtZ42TaWeNy99uYsaeTCFJ0p7gLZQkSU2b2aBKMp9k0zL1\nfXqSN0y5j9cm2ZLk3Cn3M/ZxTPLZJfTbu+0Sa7xznHZaPkkOSvJ7y12HJmdmg2oG/B5wXFW9ZLkL\n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\nqCRJTfs/nrh65z2bgeIAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb3a1a53630>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fp = collections.Counter(every_nth(scb, 6)[4])\n",
+ "plot_frequency_histogram(fp)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 134,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py:403: 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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\nSWrNoJIktfZ/P0g7wO6fxMgAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fb3a1a074e0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "fp = collections.Counter(every_nth(scb, 32)[0])\n",
+ "plot_frequency_histogram(fp, sort_key=fp.get)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'etoainhsrdlumwycfgpbvkxjqz'"
+ ]
+ },
+ "execution_count": 38,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ltrs = [p[0] for p in english_counts.most_common()]\n",
+ "cat(ltrs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 205,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'eglsmtapwcryfvxhkdziqnjoub'"
+ ]
+ },
+ "execution_count": 205,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ctls = [p[0] for p in collections.Counter(sanitise(cb)).most_common()]\n",
+ "cat(ctls)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 206,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{'a': 'h',\n",
+ " 'b': 'z',\n",
+ " 'c': 'd',\n",
+ " 'd': 'g',\n",
+ " 'e': 'e',\n",
+ " 'f': 'm',\n",
+ " 'g': 't',\n",
+ " 'h': 'c',\n",
+ " 'i': 'b',\n",
+ " 'j': 'x',\n",
+ " 'k': 'f',\n",
+ " 'l': 'o',\n",
+ " 'm': 'i',\n",
+ " 'n': 'k',\n",
+ " 'o': 'j',\n",
+ " 'p': 's',\n",
+ " 'q': 'v',\n",
+ " 'r': 'l',\n",
+ " 's': 'a',\n",
+ " 't': 'n',\n",
+ " 'u': 'q',\n",
+ " 'v': 'w',\n",
+ " 'w': 'r',\n",
+ " 'x': 'y',\n",
+ " 'y': 'u',\n",
+ " 'z': 'p'}"
+ ]
+ },
+ "execution_count": 206,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trans = {pr[1]: pr[0] for pr in zip(ltrs, ctls)}\n",
+ "trans"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 208,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'jlejidqmegwnitxeoectwucgkwrtfacizduoibeyolrmmryzfmapehmfpsolwaxqepnnidhsjhnaxqaseidvmombyitaehntlnjbeuuiwxweqhqtobjyrmnrtmezmvomdesongrphhejhxmbiiqhleznusdnsnzlthhalnumgojehltooykeesrejlssspuphemvslojkumoiggnglalrirsqjeoesgbelrhyttqunosvtfnpdtosvojhmdcplajniefiadhlqaeehhzcprsmolqpiegidtuiecyuvalthoghhsugihqjvdhgzxxbaiznkobvtyuqfexhndmalaeciwabekydtteneuqkrigcypsxjneeuwyrnetdxabndyoqhwsqndspsgkpdcoaogwuvosdehqwxwnwwuenasecrnhasseufietqimwhpnnpveaujcelywyvmzlnpisdofsoagehifobaocztiapgtlimidsyokpdegnlxouojfacarsinvqhokhhaeoiyzyvwrsghzxqiydqrfboiegouereojckswxdzidnacceglntrsllutrbennocxsnehgsayyfwedunldgvsnfqsmcjdqidatsehdfoiikrtxxtvtcimiroenicewtbnvdraxhoatcwaduxfgbelottmwjjmsehruntzsqspayifsivlfivyieecxxuihecdmhigayodabghydrjjueztsasujsurtbmdttsasajyvsteunwdfhqdenvnxelewhvgikjihffreuygkotastqvgeakpswwymccafoljcystpbultzdfreeisdoppnndjradqrtvjbultudiissuuluyrecitgogahqtweobzlfxocgzcwwbdhcvqwcgbfdfatuezidwidnzutqwalwdwfugksdmrbcmtmnvrjlfhselhkhfdxyshfedhrohfmraumnzdsaypnpurrclnrhditpmulxmnsnogfabphnuqvtshiurihgqiksmieetisebrlfdqalplimkfasectqfapenttmcoeqoxwbgncovaesdytwourjhimkcdkpatfialhixgxuersmgwoofteaageiijmbrbkmfieegkslpuonnhqmoinoakorulkevtwscossfinayinocgofgnainnrfhhbrekiba_lqmyvdhqbamdznudyyoenoshcnhtpnowljidtpapluiworjikiyvbughsmxhrhotkrbanytxaxscovvmaejimkoradnzfahegwlltaphiovmodqzdfiirrxtdqyaozlwarggqvxqcnjeefqxvkevquyegtdnybukwenwbkqovqirybiuvxtohhgkmbkahxwoirlidvabkgnlkxiolctevsndoowvaplkdfwhswsxdxydmzlwtloasaemvgmtqfgekaixqfrnetvdpbkkfsftuuezttdtulhitreoncltxjulgmgiemeilkrcjehnueaajtuvtykqotdmeiheuupylczzlaynjntloyneylkrdgewosrvdiyvkfygkwzupcmbevjooobykqayphhxlfrnsruskwhartwoyyailwaegcfnvxojrfhdayojjfwaxsnyadmiljcdvxwjnrswonolzltmnplpswgvoktmxmbuefdtrapjyddiijhkdmrtoacehryletbwwsgnjubmbubyoqmtsaydxfwabcgehdsnotvmfslwonhxsjzzfowelmhnoeoenldfleblqtwdntjay_htviaslnuhremafovpsgkzzlyytsedxhtucytdxpgdtvfadiaftuxfunyibhfudjulobagtdbaanmzsemoejivfresanisaweehdsxvkcisehbreziwaisqtmiabskylmakeuiivtzubildxoyqslfhiktsungrgjtbkwegnhmdhaujwleapehnmbtaonotttbscpvwferahuvetpwcsxardfpmemrsetvvalpbpotpbpkiiiyyanoufhyphrltmoeckvcjtugqtttendyllqarnfutqfvetvfolsbesvmcsbwdegrejhxvcrdhytceemnezjieghknlmugutitaisaninpvvonuxpfukiigxaojrekifxdzaqryehmuwrweqsuxtrgsolnpweeydfoaojtotcrqbcuvpnecihqebsbngeraoahvqttcectsoedloptsiikiawonkeydvrxnhhwwatjcyqkrwddzdmabcrrtnkyvntxqfvttlpgrnpifaqreotelttbpefmmonemplmaletrtwwbucfmkoeymktvnyghzhytfvgedxnaehyuxydvlhocuouazpqhwsboi_cpksxhpuwmthyijrstoiparxvebpenmsainitowroobnabaiyrwuhpapdtxwacpetunxbpmmssylpkiufrbvqnaewirqkhqiashruerusbimkpctbtscfwngyxgwfojetstogbifcgoochlvhbghfvsquakeitrimehdwgooeyssirvhhmjhadacgcpymhkorwrsbimteeeepaforpkkdwpeunyuficggwohtsehrntzcaebdnhbaneutrwrjhemrwdayifdteqtvcgesridembasiutoerkcwewcuewgtnedjwlrfsmhugftrjoistwrpnyssglrayxwohdgupkwrlnzitrysktdqpeocspvmjtitteripjoxstayhlmpmygczsraysazdfobntflnmwyayothutkwmtrwdccltwrgaiuemwreovsaodncuxobxnnzwtsojimfteuctdgxycehuwabnnzusxeaopuytbphtlfpppekubibaryajxlsjtlmqszuhwqowddzifiarazvnfidrordxipjixxwenailtpurhydnatshpldjourbdthupertwrfeokusxepzf_ncbtlahkqnowpaycpxnmwsbzsdnrenzekalhepmnhsooossoeanoltjrobcmeoljnldhqlmhygluweceunyieoosekdjanteccubfdgexshiqtxbrhzturwovlxwhrvetzfremjmltiysmcoqmyghilqmbpomepkyeenmbamjhilsjreezkshfyoclvhyraivwoiplfllhbtetovftoeydtfaaietcaaphzqwkokccrrwiylnivdbeetvnarcnzfmaaenfltrweawltmyoocdtfydatkxobomimuommjrvtmvmjyvtvygjhhkjyrccqtcrayzzbtuclyfxhbwnfdtruwkkkwpckgriwgwseivthbojgmnmlunzukonjrysftypkclcawoqroxtzncoauoihgpswfbonnfmaasihsgibncmufxejbnvwaonkwdtarnkimshlmcygnxhsgorvaikerhwxvdnqlflyeltdcaurjczfayyataqoypaiivtoggzhrhueeslvriaakfnyboqcsdiannpotmwyqydcxckregthbuhrdwalnehhdrxoszlsupgbimttarlultovoq+'"
+ ]
+ },
+ "execution_count": 208,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tt = ''.maketrans(trans)\n",
+ "scb.translate(tt)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 209,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1.0908179994726204"
+ ]
+ },
+ "execution_count": 209,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "index_of_coincidence(scb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 210,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1.7308339625731206"
+ ]
+ },
+ "execution_count": 210,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "index_of_coincidence(pa)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 211,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 1.0908179994726204\n",
+ "2 1.099668497740292\n",
+ "3 1.1021653664156914\n",
+ "4 1.1105288756624214\n",
+ "5 1.1202834460110789\n",
+ "6 1.1272995211118115\n",
+ "7 1.144912989343247\n",
+ "8 1.132083994267313\n",
+ "9 1.13300581113018\n",
+ "10 1.1675967871496329\n",
+ "11 1.1458117729611275\n",
+ "12 1.1594351409944323\n",
+ "13 1.1568381391323794\n",
+ "14 1.1976214763656394\n",
+ "15 1.1789430872547393\n",
+ "16 1.1862470498847197\n",
+ "17 1.1937916983613972\n",
+ "18 1.1903491796283683\n",
+ "19 1.1953937134054176\n",
+ "20 1.2108314568679621\n",
+ "21 1.2178563307567305\n",
+ "22 1.1967669671915482\n",
+ "23 1.2228893244042363\n",
+ "24 1.22779954730535\n",
+ "25 1.2434971631996035\n",
+ "26 1.2277106603385646\n",
+ "27 1.2317044827920967\n",
+ "28 1.2727713048928173\n",
+ "29 1.2410834502022665\n"
+ ]
+ }
+ ],
+ "source": [
+ "for i in range(1, 30):\n",
+ " print(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 212,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(1, 1.0908179994726204),\n",
+ " (2, 1.099668497740292),\n",
+ " (3, 1.1021653664156914),\n",
+ " (4, 1.1105288756624214),\n",
+ " (5, 1.1202834460110789),\n",
+ " (6, 1.1272995211118115),\n",
+ " (8, 1.132083994267313),\n",
+ " (9, 1.13300581113018),\n",
+ " (7, 1.144912989343247),\n",
+ " (11, 1.1458117729611275),\n",
+ " (13, 1.1568381391323794),\n",
+ " (12, 1.1594351409944323),\n",
+ " (10, 1.1675967871496329),\n",
+ " (15, 1.1789430872547393),\n",
+ " (16, 1.1862470498847197),\n",
+ " (18, 1.1903491796283683),\n",
+ " (17, 1.1937916983613972),\n",
+ " (19, 1.1953937134054176),\n",
+ " (22, 1.1967669671915482),\n",
+ " (14, 1.1976214763656394),\n",
+ " (20, 1.2108314568679621),\n",
+ " (21, 1.2178563307567305),\n",
+ " (23, 1.2228893244042363),\n",
+ " (26, 1.2277106603385646),\n",
+ " (24, 1.22779954730535),\n",
+ " (27, 1.2317044827920967),\n",
+ " (29, 1.2410834502022665),\n",
+ " (25, 1.2434971631996035),\n",
+ " (28, 1.2727713048928173)]"
+ ]
+ },
+ "execution_count": 212,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)\n",
+ " for i in range(1, 30)]\n",
+ "sorted(ics, key=lambda p: p[1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 213,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'etoainhsrdlumwycfgpbvkxjqz'"
+ ]
+ },
+ "execution_count": 213,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ltrs = [p[0] for p in english_counts.most_common()]\n",
+ "cat(ltrs)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 214,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['alsgeipmvxtrdkhycfwnzqoujb',\n",
+ " 'gsmplteracfhwvydizxkqjnoub_',\n",
+ " 'egwsctmvflaqkrhzpdjnuxbyio',\n",
+ " 'etgmlywsapfvxrqunzcjodihkb_',\n",
+ " 'lexgpscwyrfmkndatvzqhjoiub',\n",
+ " 'egmtpwsalyfchrjixvkbzondqu+_']"
+ ]
+ },
+ "execution_count": 214,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ctlss = [cat(p[0] for p in collections.Counter(section).most_common()) for section in every_nth(scb, 6) ]\n",
+ "ctlss"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 215,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[{'a': 'e',\n",
+ " 'b': 'z',\n",
+ " 'c': 'f',\n",
+ " 'd': 'm',\n",
+ " 'e': 'i',\n",
+ " 'f': 'g',\n",
+ " 'g': 'a',\n",
+ " 'h': 'y',\n",
+ " 'i': 'n',\n",
+ " 'j': 'q',\n",
+ " 'k': 'w',\n",
+ " 'l': 't',\n",
+ " 'm': 's',\n",
+ " 'n': 'b',\n",
+ " 'o': 'x',\n",
+ " 'p': 'h',\n",
+ " 'q': 'k',\n",
+ " 'r': 'u',\n",
+ " 's': 'o',\n",
+ " 't': 'l',\n",
+ " 'u': 'j',\n",
+ " 'v': 'r',\n",
+ " 'w': 'p',\n",
+ " 'x': 'd',\n",
+ " 'y': 'c',\n",
+ " 'z': 'v'},\n",
+ " {'a': 'r',\n",
+ " 'b': 'z',\n",
+ " 'c': 'd',\n",
+ " 'd': 'c',\n",
+ " 'e': 'h',\n",
+ " 'f': 'l',\n",
+ " 'g': 'e',\n",
+ " 'h': 'u',\n",
+ " 'i': 'f',\n",
+ " 'j': 'k',\n",
+ " 'k': 'b',\n",
+ " 'l': 'i',\n",
+ " 'm': 'o',\n",
+ " 'n': 'x',\n",
+ " 'o': 'j',\n",
+ " 'p': 'a',\n",
+ " 'q': 'v',\n",
+ " 'r': 's',\n",
+ " 's': 't',\n",
+ " 't': 'n',\n",
+ " 'u': 'q',\n",
+ " 'v': 'w',\n",
+ " 'w': 'm',\n",
+ " 'x': 'p',\n",
+ " 'y': 'y',\n",
+ " 'z': 'g'},\n",
+ " {'a': 'l',\n",
+ " 'b': 'x',\n",
+ " 'c': 'i',\n",
+ " 'd': 'g',\n",
+ " 'e': 'e',\n",
+ " 'f': 'r',\n",
+ " 'g': 't',\n",
+ " 'h': 'y',\n",
+ " 'i': 'q',\n",
+ " 'j': 'p',\n",
+ " 'k': 'm',\n",
+ " 'l': 'd',\n",
+ " 'm': 'h',\n",
+ " 'n': 'b',\n",
+ " 'o': 'z',\n",
+ " 'p': 'f',\n",
+ " 'q': 'u',\n",
+ " 'r': 'w',\n",
+ " 's': 'a',\n",
+ " 't': 'n',\n",
+ " 'u': 'v',\n",
+ " 'v': 's',\n",
+ " 'w': 'o',\n",
+ " 'x': 'k',\n",
+ " 'y': 'j',\n",
+ " 'z': 'c'},\n",
+ " {'a': 'r',\n",
+ " 'b': 'z',\n",
+ " 'c': 'p',\n",
+ " 'd': 'k',\n",
+ " 'e': 'e',\n",
+ " 'f': 'l',\n",
+ " 'g': 'o',\n",
+ " 'h': 'j',\n",
+ " 'i': 'x',\n",
+ " 'j': 'b',\n",
+ " 'k': 'q',\n",
+ " 'l': 'i',\n",
+ " 'm': 'a',\n",
+ " 'n': 'f',\n",
+ " 'o': 'v',\n",
+ " 'p': 'd',\n",
+ " 'q': 'y',\n",
+ " 'r': 'w',\n",
+ " 's': 's',\n",
+ " 't': 't',\n",
+ " 'u': 'c',\n",
+ " 'v': 'u',\n",
+ " 'w': 'h',\n",
+ " 'x': 'm',\n",
+ " 'y': 'n',\n",
+ " 'z': 'g'},\n",
+ " {'a': 'c',\n",
+ " 'b': 'z',\n",
+ " 'c': 'h',\n",
+ " 'd': 'y',\n",
+ " 'e': 't',\n",
+ " 'f': 'l',\n",
+ " 'g': 'a',\n",
+ " 'h': 'v',\n",
+ " 'i': 'j',\n",
+ " 'j': 'k',\n",
+ " 'k': 'm',\n",
+ " 'l': 'e',\n",
+ " 'm': 'u',\n",
+ " 'n': 'w',\n",
+ " 'o': 'x',\n",
+ " 'p': 'i',\n",
+ " 'q': 'b',\n",
+ " 'r': 'd',\n",
+ " 's': 'n',\n",
+ " 't': 'f',\n",
+ " 'u': 'q',\n",
+ " 'v': 'g',\n",
+ " 'w': 's',\n",
+ " 'x': 'o',\n",
+ " 'y': 'r',\n",
+ " 'z': 'p'},\n",
+ " {'a': 's',\n",
+ " 'b': 'b',\n",
+ " 'c': 'u',\n",
+ " 'd': 'j',\n",
+ " 'e': 'e',\n",
+ " 'f': 'l',\n",
+ " 'g': 't',\n",
+ " 'h': 'm',\n",
+ " 'i': 'c',\n",
+ " 'j': 'y',\n",
+ " 'k': 'p',\n",
+ " 'l': 'r',\n",
+ " 'm': 'o',\n",
+ " 'n': 'x',\n",
+ " 'o': 'k',\n",
+ " 'p': 'i',\n",
+ " 'q': 'q',\n",
+ " 'r': 'w',\n",
+ " 's': 'h',\n",
+ " 't': 'a',\n",
+ " 'u': 'z',\n",
+ " 'v': 'g',\n",
+ " 'w': 'n',\n",
+ " 'x': 'f',\n",
+ " 'y': 'd',\n",
+ " 'z': 'v'}]"
+ ]
+ },
+ "execution_count": 215,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trans = [{pr[1]: pr[0] for pr in zip(ltrs, ctls)} for ctls in ctlss]\n",
+ "trans"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 216,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['ezfmigaynqwtsbxhkuoljrpdcv',\n",
+ " 'rzdchleufkbioxjavstnqwmpyg',\n",
+ " 'lxigertyqpmdhbzfuwanvsokjc',\n",
+ " 'rzpkelojxbqiafvdywstcuhmng',\n",
+ " 'czhytlavjkmeuwxibdnfqgsorp',\n",
+ " 'sbujeltmcyproxkiqwhazgnfdv']"
+ ]
+ },
+ "execution_count": 216,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[cat(t[l] for l in sorted(t)) for t in trans]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 217,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['gnyxacfpeuqtdiswjvmlrzkohb',\n",
+ " 'pkdcgizelojfwtmxuarshqvnyb',\n",
+ " 'snzlepdmcyxaktwjifvgqurbho',\n",
+ " 'mjupenzwlhdfxygckastvoriqb',\n",
+ " 'gqarltvcpijfksxzuywemhnodb',\n",
+ " 'tbiyexvspdofhwmkqlagczrnju']"
+ ]
+ },
+ "execution_count": 217,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[cat([k for k in t if t[k] == l][0] for l in sorted(t.values()))\n",
+ " for t in trans]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 218,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['xsevuujlekgasepee eyes nvjbwoomhyoxprrsfeme wplrhobwlagtsgbcdewr tpc tv lnhpcixrnskzoaeahqgi',\n",
+ " 'rxooaterftunzxtdcosb gejrvoecxpolfnalezlq tlie irl co gcsijlblcsovrdeznjd hahn x was etw trl mize',\n",
+ " 'cwa idm we iaoexwhafgrvehryiwtj bnlrscgtywosoasijjei tim few ssd etc rata uomavdtiiqtjllhmvs',\n",
+ " 'avfoibhshsuqaetsezyg sigi wcpo ich pad shy mr qos trejerfnyoeqzyhsmzp bjhsznfeckeknqpiklth los',\n",
+ " 'aevortqewffetefecqbh ujypcdkklhengfpneohy of nporjrsdqafacdyxvdy in rmwjyeifhlcgyrn sure',\n",
+ " 'ltfevnlradiecbheazsl srp alguendxuewogdvrzdav of pep hiaktssbdxnryztanvme wal of akiwvfhgtdytydvmhy',\n",
+ " 'to duakqliwseteiufzpu us imrxbqoddvhmctoeke dime ixmbasbhbsdnsvmicwt an hswnannhntemqanecjht',\n",
+ " 'kmmgidjtdumvftmzhlyv hzsdaoieedmiuobmtbkt key al opie tumiwtxfqfmabcroeyu nuckmkjeuitolgxjrdts',\n",
+ " 'pynozijacsoowahydpsv katey kpnusiuilcomtkihhncl mhnxjjezthtfnxicmtxl uaefsihxpudaecnspmsj det',\n",
+ " 'baqhwegskchfxoebmhtd dcbiahhevyyeoxcdggdl yjnptszjoiagqndtzdmh tesa iipvlnivshfqoobknyw or us of dr',\n",
+ " 'du ykhtmsegiyheqtutrnzw qkrycxjggndljbzrugxm uwt tnt bsd saha zytcghuwiumdmxfplnnu',\n",
+ " 'rolakmzwmshhwrwswdpm is whirsrebrhndgnxpihdg ngrnpuwtssfotgldukrt i at cms jvenjcbthrhnsoecvawi go',\n",
+ " 'eea ohhqhdpfqawpwslbqnii utc mhvhnoalyieceyrfgtv rktedhfawdnskeorfvub gao moos lakjqyehilmwdimtitak',\n",
+ " 'to sjr xscblmatemxfwpdtnnrq lt on in xtmjwwekesdvrhamafhd on i vjtbgtnolnoqcsnmefuc',\n",
+ " 'o_wclfkdlcjhgdxtrudp def rhrytctvndudksdtgnvu yhuenxobaoqnygrilqro re tbmqsffakabimtvulnex or fen',\n",
+ " 'odnzmhehgudwatcrur kldp qbfbhasnqeicohtzwunn mcvykzynzetpjkuftqjy key tfnkxrxrhnujxjiucun',\n",
+ " 'dfhnbyailryxgfbscyri hhdofvaxwjlsbburuute bild dig qogwfhprrfuiyfkkplbu wt we hhtelbjgevqyebthbqpp',\n",
+ " 'neobuvfbfmiwejntbaei or we othtrluwokkcsglyoi lead xpuzecachasxtcvtmwz teil to ehjnpfuuxzdhdnztawtp',\n",
+ " 'neow bmi ktgtaoyhodvbqojbwxnp mgfeyxrtiqmwzopcrcyu bot in ca buch pesi of oowunemumtbytjoqcuop dv',\n",
+ " 'xprt pdf fodradkydubgklmfu eats x wall gwgigmvdfalqlqntpfeo sp kddi a uk exil st',\n",
+ " 'ttyecndseojgragtxdnl qnjftqroihddpqghnuge cuhndoblwawueaekfvzb wise dlen de eels iqdensvogulezso_eeu',\n",
+ " 'an iunjrsegtmibvhcbzzwd ptdtuqrtnvfadpgyuavm shoo btn kpcnkajswyivrwtfak aunt at lb hhr it',\n",
+ " 'ksvmhtionhdngihlpiyk xyaieefoezorthdqtgoa xix dsr sweco hyabcfhwhytpvddpeobo idl',\n",
+ " 'cokxtnxseyaelirndxww envir nlj to in iata ffjpqrbehnscveopgy apssuwgrelnhhtybhugq get',\n",
+ " 'vfcfuospksfrcblmps pst lee yxujxtccvoatinimdwj to tmdaqmyttkbdwiciaulv in wieynijlbbmpdlmam',\n",
+ " 'ihrttbxoekcxlsrnydao tsui on htpqkinnkvwybaujqtdv se bomb hboqomtsgyshgejajb an mad',\n",
+ " 'wfvrhemhpttdvarauocj mcv ctt msr vejinngeshttlyqtauej a it hi we vaah a woo wdt wed duh',\n",
+ " 'kaersuntxukcwnrdizhl of yhstlxkyftqqmyatuggh fvs bac set eewatngeqlltnelpwgt we an a',\n",
+ " 'wsxrmwlbitfgxtyffmrx rotwvgehylterodqpiyd stujirhzgvrginih_vvb apr pdrltrooxmfoeovtob ben get lio on',\n",
+ " 'a arr mdi ja of a a on rylgnvfepunmvhtnfyng rl ii dscfudwmqyqaohsaszbr van iemjesdhfhlwvyeqoi',\n",
+ " 'mwwnkoymwmixeaatiycs byker yrwyccmrmyizctbeutpo recur cd it fha hhbselzrnuougjpfgrb is gpa q alti',\n",
+ " 'heep hwiogwxfwceradymavjm wdr a ii rota by tex hae fatt dams hx silo uhh do mpaejeujyehmhptlntf art',\n",
+ " 'th of vgiwyntgmenehkrsoqi leygqanxihdagpgnmiim so so yrilpydvxshdazothoi be icp etufgblxehoaepocvey',\n",
+ " 'he am cwggrmymzaosoioziqec lemwflrpameteytfglam spvmueshyhsyelgniiud nrfnynkrnkntzgaadvul ween',\n",
+ " 'vtfcpmveeyssjalzjdke oic not ngl odpvgcewdnoqssfojpwi kasr cibc rscegfdxamoomazbawoi he',\n",
+ " 'nfkhgxoqksefhsstgrn epitnthrcwhktyoxhtey cest rm me ex cape pbw_njjtutlfqatwcso mvknlginzfpfninxewhu',\n",
+ " 'regla eadie i hi esf rue zhecyleidklsirqwgrkk ddr hyer a doe ie ii xiv naah yjrcwdgekieovokcprx or',\n",
+ " 'nr iuwkgemueabwmelxlueh mil yivlojeowclcvirepxd he tlc olzruwhjoetbbalqory sur on oouueovsmwdsneeoeq',\n",
+ " 'we deo uab as ueauaspszqsfexyuoh gods nabu nheobaomytzpgtaefpue out hrstlortuiomffttfkrn',\n",
+ " 'iraldtlrvsqalulxfkeu my kerb von yuvovnopxzjtcuwmmyef stm uamjuwxbwcjwjposkgii ouocctjglfluynzrxtnz',\n",
+ " 'hoiwekgwmuuauezpipoz ayia neo eccd gpn in tm lot facimoqtvlcbpexclvs sea bwi on nlxhlisulymyaqrfkenk',\n",
+ " 'thft new pyha jsmwoeueijndpjyzmhdp a on ztpcsuokedkybemlnteh suhuhoxmtoctqydhoonn get',\n",
+ " 'gwkcouykyfsemelxrspd ssda irl psy tax wi dvcqaltatowrwaiuiq+']"
+ ]
+ },
+ "execution_count": 218,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "sections = []\n",
+ "for tr, section in zip(trans, every_nth(scb, 6)):\n",
+ " tt = ''.maketrans(tr)\n",
+ " sections += [section.translate(tt)]\n",
+ "tpack(segment(combine_every_nth(sections)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 219,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'oreomcufedvtmgjelehgvyhdnvwgkshmbcylmiexlrwffwxbkfszeafkzplrvsjuezttmcapoatsjuspemcqflfixmgseatgrtoieyymvjveuauglioxwftwgfebfqlfcepltdwzaaeoajfimmuarebtypctptbrgaasrtyfdloeargllxneepweorpppzyzaefqprlonyflmddtdrsrwmwpuoelepdierwaxgguytlpqgktzcglpqloafchzrsotmekmscaruseeaabhzwpflruzmedmcgymehxyqsrgaldaapydmauoqcadbjjismbtnliqgxyukejatcfsrsehmvsienxcggeteyunwmdhxzpjoteeyvxwtegcjsitcxluavputcpzpdnzchlsldvyqlpceauvjvtvvyetspehwtasppeykmegumfvazttzqesyoherxvxqfbrtzmpclkplsdeamklislhbgmszdgrmfmcpxlnzcedtrjlylokshswpmtqualnaaselmxbxqvwpdabjumxcuwkilmedlyewelohnpvjcbmctshhedrtgwprrygwiettlhjpteadpsxxkvecytrcdqptkupfhocumcsgpeacklmmnwgjjgqghmfmwletmhevgitqcwsjalsghvscyjkdierlggfvoofpeawytgbpupzsxmkpmqrkmqxmeehjjymaehcfamdsxlcsidaxcwooyebgpspyopywgifcggpspsoxqpgeytvckaucetqtjerevaqdmnomakkweyxdnlgspguqdesnzpvvxfhhsklrohxpgziyrgbckweempclzzttcowscuwgqoiyrgycmmppyyryxwehmgdldsaugvelibrkjlhdbhvvicahquvhdikcksgyebmcvmctbyguvsrvcvkydnpcfwihfgftqworkaperanakcjxpakecawlakfwsyftbcpsxztzywwhrtwacmgzfyrjftptldksizatyuqgpamywmadumnpfmeegmpeiwrkcusrzrmfnkspehgukszetggfhleuljvidthlqsepcxgvlywoamfnhcnzsgkmsramjdjyewpfdvllkgessdemmofiwinfkmeednprzylttauflmtlsnlwyrneqgvphlppkmtsxmtlhdlkdtsmttwkaaiwenmis_rufxqcauisfcbtycxxletlpahtagztlvromcgzszrymvlwomnmxqiydapfjawalgnwistxgjsjphlqqfseomfnlwsctbksaedvrrgszamlqflcubckmmwwjgcuxslbrvswdduqjuhtoeekujqnequyxedgctxiynvetvinulqumwximyqjglaadnfinsajvlmwrmcqsindtrnjmlrhgeqptcllvqszrnckvapvpjcjxcfbrvgrlspsefqdfgukdensmjukwtegqczinnkpkgyyebggcgyramgwelthrgjoyrdfdmefemrnwhoeatyessogyqgxnulgcfemaeyyzxrhbbrsxtotgrlxtexrnwcdevlpwqcmxqnkxdnvbyzhfieqolllixnusxzaajrkwtpwypnvaswgvlxxsmrvsedhktqjlowkacsxlookvsjptxscfmrohcqjvotwpvltlrbrgftzrzpvdqlngfjfiyekcgwszoxccmmoancfwglsheawxregivvpdtoyifiyixlufgpsxcjkvsihdeacptlgqfkprvltajpobbklverfatleletrckreirugvctgosx_agqmsprtyawefsklqzpdnbbrxxgpecjagyhxgcjzdcgqkscmskgyjkytxmiakycoyrlisdgcisstfbpefleomqkwepstmpsveeacpjqnhmpeaiwebmvsmpugfmsipnxrfsneymmqgbyimrcjlxuprkamngpytdwdoginvedtafcasyovreszeatfigsltlgggiphzqvkewsayqegzvhpjswckzfefwpegqqsrzizlgziznmmmxxstlykaxzawrgflehnqhogydugggetcxrruswtkygukqegqklrpiepqfhpivcedweoajqhwcaxgheeftebomedantrfydygmgsmpstmtzqqltyjzkynmmdjslowenmkjcbsuwxeafyvwveupyjgwdplrtzveexcklsloglghwuihyqztehmaueipitdewslsaqugghehgplecrlzgpmmnmsvltnexcqwjtaavvsgohxunwvccbcfsihwwgtnxqtgjukqggrzdwtzmksuwelgerggizekffltefzrfsregwgvviyhkfnlexfngqtxdabaxgkqdecjtseaxyjxcqralhylysbzuavpilm_hznpjazyvfgaxmowpglmzswjqeizetfpsmtmglvwllitsismxwvyazszcgjvshzegytjizffppxrznmykwiqutsevmwunaumspawyewypimfnzhgigphkvtdxjdvkloegpgldimkhdllharqaidakqpuysnemgwmfeacvdllexppmwqaafoascshdhzxfanlwvwpimfgeeeezsklwznncvzeytxykmhddvlagpeawtgbhseictaisteygwvwoaefwvcsxmkcgeugqhdepwmcefispmyglewnhvevhyevdgtecovrwkpfaydkgwolmpgvwztxppdrwsxjvlacdyznvwrtbmgwxpngcuzelhpzqfogmggewmzoljpgsxarfzfxdhbpwsxpsbcklitgkrtfvxsxlgaygnvfgwvchhrgvwdsmyefvwelqpslcthyjlijttbvgplomfkgeyhgcdjxheayvsittbypjeslzyxgizagrkzzzenyimiswxsojrpogrfupbyavulvccbmkmswsbqtkmcwlwcjmzomjjvetsmrgzywaxctsgpazrcolywicgayzewgvwkelnypjezbk_thigrsanutlvzsxhzjtfvpibpctwetbensraezftaplllpplestlrgowlihfelrotrcaurfaxdryveheytxmellpencostgehhyikcdejpamugjiwabgywvlqrjvawqegbkwefofrgmxpfhlufxdamrufizlfeznxeetfisfoamrpoweebnpakxlhrqaxwsmqvlmzrkrraigeglqkglexcgkssmeghsszabuvnlnhhwwvmxrtmqcieegqtswhtbkfssetkrgwvesvrgfxllhcgkxcsgnjlilfmfylffowqgfqfoxqgqxdoaanoxwhhughwsxbbigyhrxkjaivtkcgwyvnnnvzhndwmvdvpemqgailodftfrytbynltowxpkgxznhrhsvluwljgbthlsylmadzpvkilttkfsspmapdmithfykjeoitqvsltnvcgswtnmfparfhxdtjapdlwqsmnewavjqcturkrxergchsywohbksxxsgsulxzsmmqglddbawayeeprqwmssnktxiluhpcmsttzlgfvxuxchjhnwedgaiyawcvsrteaacwjlpbrpyzdimfggswryrglqlu+'"
+ ]
+ },
+ "execution_count": 219,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "scb = cat(c.lower() for c in cb if c != ' ') + '+'\n",
+ "scb"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 220,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "3588"
+ ]
+ },
+ "execution_count": 220,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(scb)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 221,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "6.0"
+ ]
+ },
+ "execution_count": 221,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(scb) / 598"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 223,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'okrahtrvugzheefqniocxmpgmyqsjrctcpasurarzafcutynediyvudqsaftvpfwglttceavmkbfxzgutsmsjpykoxefclwhlhxqpzeoxzgjhclpltguedmfvmtnzvyclbsphspbwidgarjbnphxqpvetxecwaagitgcgpzwkkzeeesltctthmljfbmmvapebnrgsncwoymsygmhtrljcxmamjgggeigzclzeqsjvfxgzzwtlhrdlarmyclpwfmgilfmvqtlfwlkslwlwsipxeocspbtmmmlkmnsxefhmkwssexgvtzvqyylegijaraiykzgftdysokqatzwzcpxclpwfmgilsjijhrjaavfvawkseslayhljslczruggoeoehnygtzvwryrtsiltctcsijamytsiucjxdzrakggffpdjcfaoisipxaejspdtrpsxrslhtryjglfzvugqbnesfqpmhpvfeyeeosfkymoelwtcfoeixqpmoqmfefmuelanqtlfwlksliywwepxtsevemgcpmngbtswcspbtuoeukmnsapspattzasuggsevmerxdeshtmvephokraayiprcwiemgpykyqsjecyrzqwdmkanyevmmhpjjqlmipvxqpmaemfefmuelanuaecizguhuwhjgjbegiljcbiwiykmgaommvpbxamshgwewmkyfhwpvwtcjutvwfggdlgacfxqfmumjredxsdjbssivvfxlpkaqlbnlwlcrxoqfsvreecisfggedwspbpadngklxdelwtcuydedwqmifwojmmozouqkfayhghraetbdgeboylmogeilxapemhpjskraffpucrhiyjjqlmoqlaumpnxifuyeudxawqpadrgurkaeiykqmbfxaprtcemuuygdnyfpgggsicpcpnztstyelppxtmftsidgeboywwzrxndmngqvofxapegeeagtiaesevnctryivvfttnediyvudlsfcltlfdkqaeolaufxaoumcpmecwapraexsmprtiywogqmoqwltyvaeljqraexejefbnrgsoneelzapevaesapaaackwqdtsxednfhlomfidhrnighrponszqpmslxapaatfxzkjlawykvgnszwlglmaemgwqeywivvfxrpwlqdmhpmpnczizrlqqmrlgsvfkosikgrnpneerygdweafutseilqraegmdnyzedejqsgdsmekltnlglqdzrzwkrphvzgsvghnlrvepnewxqjcxmfpsvcwhtwzgphccekuslkysoklztselvfxmlrqeyeeosfkgphzwmhdxrphsipnedsegcgdzrzkqvawivqlbayasauxrprgvggvzpngbpielucjzanykclwhtwjgthlexzgwpecibwqmfzhvgpbnsmkcrmextlvmirzzgmctczrxtmgtlxaqltssicpcptsiqosltelweyeeosfkygacqagqfudxwtcwfzvshggawwzquwohrokratsidgeboyeffktrnlwfmgsevseymhcskcjnsemmuqxtsmkhmkcpwokraptgcgryeygwuygdevsrquueeycggsexzgqvawighraenedgbhntefhmkcpxzgpxwlwdkrmlplgrchfdyueclsysfgraewikuubtsxzggkpcmvgymseecgygdlgugnmiykljcbrqelgraewiykmgnlmjgqhfelwkvmhhelefxdlrvyybtphlqhhiyfsvreefrvgpvogijqdwacofgqlayhtgdhrpefaqdicqaufvofpvdcvoyhmerxddedwqmifwkgakeepqucmofxokraadqsnjyocgwqdaayhhkadeowgnbbecwojmaaoxjctxlwivygmhsmehphmcsegubtsevgtbofwhnygtzwlgyetsiuqbxxqvgopbgsxmpbxrnediyvudrguclawykvgnshekctxrjyfrjxadefvktnmyljcpadaafceycisfygdvrwymytsizgzkehxsnchfrmvgmghpwwvfbsrystbttviqrmbnewstmnnoxzgnxrtqwvckoqxzgatlphgpgtnneerygdtrljcweaxzumyntkzvuaeyednkxnlvwcrmhpmjnmpedxwdzmhpcjqqxadsfgzkeloapevogijclwmloapegotwwngdelqmefeackwtykmjmfvfxczrxwqboywsnslttykujbefxwpygtdxgncbnesljcvaxtspbfaoisyyrwtxzvfxczhwzpxtfvfklziexguyeudxawqphzvwoybnphljphurlgwrttlwshcwidxspaxppvzcnlslpmurbudgstcwnzxzklzfzvljcyaeighraetbljjxgtsfrckhltkkrldpwltsvttsfyylplvlqdwoxmlkygsapsplxdcinglzezvhgpaaawavutsuykvywigijughnlvqvyvttglqftvpxzgkvaxtwfymsevseymhcstwrmhpsmvahmpasuraedeegphudivdwmhpwmtnkidiapttstsfqdmhpmjeyfpelweyeeosfkygwlvjkmkswempaaeoeecqligisuqtuwxgpqmrlgsvfkohlsvcoeclaukhttzsvghntrspyvtzjljczrpelgqmtcisefxrjwsnslttykcztnosfgbmhpmpvfeermgprhompaxghnlrvucmofxkqsmhqsjvfxfzvlkdbeotgtrttnejtgweyazgpxhpmfvcgdphlqclcltwdwleljjqkurtxsplbahmljraensvgvaedifvywedtsvaatzgsvmhroijklzhtqlqpxtcisvubtsednyulpqwprhclvjkbxncergggcsxmvfblesljczrzyffygdwisxcgoyighraehismmkwzyffcwawmngggochwtrhpcsnkbxnzxzklzoqzsnsxtzxzgcgexckcjnsemmuygdsmkistroqmuraagiljmngsxljcrwzydfzxsljwdsmoygwomkeltjqswszrghphmplsfekodwdasgdpvwurbmlxwfatlreuwqkelpaugggbyaeieyelsvraensvgvpadpguraedilqsmtzvwemoecmloykcsmfifbsxiffmnbwilkkxiytmtqniesxvfxfwiwklzslpmurbudeffqhaegstpbdprkcjnsemmupxgcsmrcwwtxzjgltcykvwzulvvclwtsijgktiymfiahhzvludkoxmfefmuelanjxdmcljcltpevhyltxejeslfthwngnsnelqgmwlwfqreoyktgdhrpxzgnnrdyapevawivqlbayjgtaxacvaxcwbpjgtcmhpksvcloqgstpbdprspbeathkkczehmljraetvtcadsesocrxrelwtmfayjgtaxwlwltyipphljcbrdexgrrllcapykeqyygdtrzzwtraedisclwiemkhgmttryvfttelwglwiykghkrsesjaublwpagznrtivuyyewcapraetvjgdngpelpmoizqsislblxsxmkux____+'"
+ ]
+ },
+ "execution_count": 223,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "scbz = combine_every_nth(chunks(scb, 598))\n",
+ "scbz"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 224,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(1, 1.1327667419873415),\n",
+ " (2, 1.1556010990495924),\n",
+ " (3, 1.206233230791329),\n",
+ " (4, 1.2313380131157103),\n",
+ " (6, 1.2731749420011045),\n",
+ " (5, 1.2798462894967542),\n",
+ " (11, 1.327373238986224),\n",
+ " (9, 1.3278191229344554),\n",
+ " (8, 1.3293010680061772),\n",
+ " (7, 1.3398698729051908),\n",
+ " (10, 1.3463431836469604),\n",
+ " (13, 1.3620114185331578),\n",
+ " (16, 1.3629806460087397),\n",
+ " (12, 1.3915567599630554),\n",
+ " (22, 1.39335904150719),\n",
+ " (18, 1.3959171825391465),\n",
+ " (23, 1.4178260869565218),\n",
+ " (19, 1.4214635856898579),\n",
+ " (20, 1.42971529277585),\n",
+ " (26, 1.4369385555156309),\n",
+ " (14, 1.4386638862659562),\n",
+ " (21, 1.4575520319421331),\n",
+ " (15, 1.458654023723276),\n",
+ " (24, 1.4687703804347825),\n",
+ " (17, 1.4867141412505027),\n",
+ " (29, 1.5101559934318556),\n",
+ " (25, 1.556426856639952),\n",
+ " (27, 1.563057958973637),\n",
+ " (28, 1.613936964396148)]"
+ ]
+ },
+ "execution_count": 224,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(ch, i)) / i)\n",
+ " for i in range(1, 30)]\n",
+ "sorted(ics, key=lambda p: p[1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 225,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "('scytale', -4506.678592965439)"
+ ]
+ },
+ "execution_count": 225,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vigenere_frequency_break(scbz, max_key_length=30)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 226,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'withhindsightanopportunityforpeacewasthrownawaycalgacusmayhavebeenatraitorbuthewasbornaromanandhadforgedthelocaltribesintoanorganisedanddisciplinedforceitmayhavebeenpossibletotreatwithhimbringingcaledoniawithintheempireinexchangeforthegovernorshipofcaledoniabutsalustiuswasagreedyandambitiousmanforwhomvictorywaseverythinghehadnowishtosharecaledoniaorglorywithcalgacusandthusconceivedaplantorepaythetreacheryofthecaledoniiinfullhemadeagreatfanfareofpushinghisforcesintonortherncaledoniatotheremotefortofinchtuthilsalustiusinsecrethadconceivedaslyandaudaciousplancatowasinstructedtoproceedwithanexpeditionaryforcefromeboracumtothefrontierfortatinchtuthilwherehewouldrelievetheiilegionadiutrixpiafideliswhowererequiredindaciahequicklyestablishedthelegioninastateofbattlereadinessandwasjoinedtherebysalustiuswhotookcommandoftheixlegionhumiliatingthefaithfulcatoinfrontofhisownmensalustiuswasnostrategistbutintacticsandcunningheknewnoparallelfromthelegionsextensivescoutingnetworkhehadlearnedthatcalgacushadestablishedhisheadquartersinthemountainswestofstracathrothemarchingcampleavingcatoinchargeofasmallholdingforceoftwocohortsatinchtuthilsalustiusostentatiouslyledtherestoftheixlegiontostracathrohesetupcampandlaidwastetothevillagesaroundhiminanactofgrossprovocationandcrueltyheemulatedhisherocrassusknowingthatthemanycaledoniiwhosufferedagruesomeendonhiscaledonianwaywerenotinvolvedwithcalgacusandhisrevolttheywerejustfodderinhisattempttoprovokeaconfrontationasheknewtheymustthecaledonianarmiesmusteredforafinalshowdownwiththelegionandmarchedonstracathrosalustiussethisforceswithpicketfencesandtrapsbutagainstthescaleofthecaledonianforcetherewaslittlehopeofsuccessnonethelesswiththeirprideatstakeandacceptingtheirfatethelegionnairesoftheixthwatchedandwaitedtojoinbattleundercoverofdarknessandbeforeanyskirmishcouldbeconductedsalustiussecretlysetoutwithasmallforceofhandpickedsoldierswhohadtravelledwithhimfromromewithadeviousplantostealthecodexfromrightundercalgacusnosesalustiuswasaveryunpleasantmanbuthewaswidelyreadandknewofthehebrewtaleofgideonhesethisguardatkeypointsaroundtheperimeterofthecaledoniancampandinthedepthsofnightwhenallmenareattheirlowestebbtheyroseasonebreakingcoverandmakingnoiselikeamuchlargerarmyintheconfusionsalustiusslieutenantstoleintothecampandmadeawaywiththecodexreturningittosalustiuswhoremainedthroughoutatasafedistanceperhapssalustiuscarednothingforthefateoftheixthlegionperhapsitsdestructionwaspartofdomitiansplannedrevengeorperhapsitwasjustadiversionarytactictohavethemcampedatstracathrobuttheoutcomewasthesamerousedbythesurpriseinvasionoftheircampthecaledonianwarriorslaunchedamassiveassaultonstracathrowhateverhismotivationinanactofthegreatesttreacherysalustiusabandonedtheixthlegiontooblivionandsetoutsouthforthefortifiedportatcarridenwhereheintendedtoescapebyseafrombritanniawiththecodexhesentadespatchtocatoorderinghimtoretreatwithallablementocarridenrazeinchtuthiltothegroundandleavenoneoftheweakorwoundedaliveinordertoprovidenothingofvaluetotheenemysalustiusandhisguardmusthavethoughttheywouldbesafebutoncemoreaproudsonofromehadgrosslyunderestimatedcalgacusrealisingquicklythatthecodexwaslosthesetouttorecoveritmarchinghismendoubletimeinpursuitofthefleeingsalustiusandsoatcarridensalustiusregroupedwithhistrustyguardandtheremainingcohortsfrominchtuthilledbythesteadfastmarcusfideliuscatoitwasnotlongbeforethepursuingcaledonianforcearrivedbeforethegatesofcarridenandlaidsiegewiththeirbackstowatertheromanforcewastrappedtheirsafetylayinarefugefarovertheseaanditisfittingthattheendingofmystorywilllieburiedsafelyintheirrefugeatnoviomagusbatavorum____+'"
+ ]
+ },
+ "execution_count": 226,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "vigenere_decipher(scbz, 'scytale')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 227,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "with hindsight an opportunity for peace was thrown away cal gac us may have been a traitor but he\n",
+ "was born a roman and had forged the local tribes into an organised and disciplined force it may have\n",
+ "been possible to treat with him bringing caledonia within the empire in exchange for the\n",
+ "governorship of caledonia but salus ti us was a greedy and ambitious man for whom victory was\n",
+ "everything he had no wish to share caledonia or glory with cal gac us and thus conceived a plan to\n",
+ "repay the treachery of the caledon ii in full he made a great fanfare of pushing his forces into\n",
+ "northern caledonia to the remote for to finch tuth ilsa lust i us in secret had conceived a sly and\n",
+ "audacious plan ca to was instructed to proceed with an expeditionary force from e bora cum to the\n",
+ "frontier fort at inch tuth il where he would relieve the ii legion a diu trix pia fidelis who were\n",
+ "required in dacia he quickly established the legion in a state of battle readiness and was joined\n",
+ "thereby salus ti us who took command of the ix legion humiliating the faithful ca to in front of his\n",
+ "own mensa lust i us was no strategist but in tactics and cunning he knew no parallel from the\n",
+ "legions extensive scouting network he had learned that cal gac us had established his headquarters\n",
+ "in the mountains west of s trac athro the marching camp leaving ca to in charge of a smallholding\n",
+ "force of two cohorts at inch tuth ilsa lust i us ostentatiously led the rest of the ix legion to s\n",
+ "trac athro he setup camp and laid waste to the villages around him in an act of gross provocation\n",
+ "and cruelty he emulated his hero crassus knowing that the many caledon ii who suffered a gruesome\n",
+ "end on his caledonian way were not involved with cal gac us and his revolt they were just fodder in\n",
+ "his attempt to provoke a confrontation a she knew they must the caledonian armies mustered for a\n",
+ "final showdown with the legion and marched on stra cath rosa lust i us set his forces with picket\n",
+ "fences and traps but against the scale of the caledonian force there was little hope of success\n",
+ "nonetheless with their pride at stake and accepting their fate the legionnaires of the ixth watched\n",
+ "and waited to join battle undercover of darkness and before any skirmish could be conducted salus ti\n",
+ "us secretly set out with a small force of handpicked soldiers who had travelled with him from rome\n",
+ "with a devious plan to steal the codex from right under cal gac us noses a lust i us was a very\n",
+ "unpleasant man but he was widely read and knew of the hebrew tale of gideon he set his guard at key\n",
+ "points around the perimeter of the caledonian camp and in the depths of night when all men are at\n",
+ "their lowest ebb they rose as one breaking cover and making noise like a much larger army in the\n",
+ "confusions a lust i uss lieutenant stole into the camp and made away with the codex returning it to\n",
+ "salus ti us who remained throughout at a safe distance perhaps salus tiu scared nothing for the fate\n",
+ "of the ixth legion perhaps its destruction was part of domitian s planned revenge or perhaps it was\n",
+ "just a diversionary tactic to have them camped at s trac athro but the outcome was the same roused\n",
+ "by the surprise invasion of their camp the caledonian warriors launched a massive assault ons trac\n",
+ "athro whatever his motivation in an act of the greatest treachery salus ti us abandoned the ixth\n",
+ "legion to oblivion and set out south for the fortified port at car riden where he intended to escape\n",
+ "by sea from britannia with the codex he sent a despatch to ca to ordering him to retreat with all\n",
+ "able men to car riden raze inch tuth il to the ground and leave none of the weak or wounded alive in\n",
+ "order to provide nothing of value to the enemy salus ti us and his guard must have thought they\n",
+ "would be safe but once more a proud son of rome had grossly underestimated cal gac us realising\n",
+ "quickly that the codex was los the set out to recover it marching his men double time in pursuit of\n",
+ "the fleeing salus ti us and so at car ride nsa lust i us regrouped with his trusty guard and the\n",
+ "remaining cohorts from inch tuthill ed by the steadfast marcus fidel i usca to it was not long\n",
+ "before the pursuing caledonian force arrived before the gates of car riden and laid siege with their\n",
+ "backs to water the roman force was trapped their safety lay in a refuge far over these a and it is\n",
+ "fitting that the ending of my story will lie buried safely in their refuge at novio magus\n",
+ "batavorum____+\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(lcat(tpack(segment(vigenere_decipher(scbz, 'scytale')))))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 202,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "with hindsight an opportunity for peace was thrown away cal gac us may have been a traitor but he\n",
+ "was born a roman and had forged the local tribes into an organised and disciplined force it may have\n",
+ "been possible to treat with him bringing caledonia within the empire in exchange for the\n",
+ "governorship of caledonia but salus ti us was a greedy and ambitious man for whom victory was\n",
+ "everything he had no wish to share caledonia or glory with cal gac us and thus conceived a plan to\n",
+ "repay the treachery of the caledon ii in full he made a great fanfare of pushing his forces into\n",
+ "northern caledonia to the remote for to finch tuth ilsa lust i us in secret had conceived a sly and\n",
+ "audacious plan ca to was instructed to proceed with an expeditionary force from e bora cum to the\n",
+ "frontier fort at inch tuth il where he would relieve the ii legion a diu trix pia fidelis who were\n",
+ "required in dacia he quickly established the legion in a state of battle readiness and was joined\n",
+ "thereby salus ti us who took command of the ix legion humiliating the faithful ca to in front of his\n",
+ "own mensa lust i us was no strategist but in tactics and cunning he knew no parallel from the\n",
+ "legions extensive scouting network he had learned that cal gac us had established his headquarters\n",
+ "in the mountains west of s trac athro the marching camp leaving ca to in charge of a smallholding\n",
+ "force of two cohorts at inch tuth ilsa lust i us ostentatiously led the rest of the ix legion to s\n",
+ "trac athro he setup camp and laid waste to the villages around him in an act of gross provocation\n",
+ "and cruelty he emulated his hero crassus knowing that the many caledon ii who suffered a gruesome\n",
+ "end on his caledonian way were not involved with cal gac us and his revolt they were just fodder in\n",
+ "his attempt to provoke a confrontation a she knew they must the caledonian armies mustered for a\n",
+ "final showdown with the legion and marched on stra cath rosa lust i us set his forces with picket\n",
+ "fences and traps but against the scale of the caledonian force there was little hope of success\n",
+ "nonetheless with their pride at stake and accepting their fate the legionnaires of the ixth watched\n",
+ "and waited to join battle undercover of darkness and before any skirmish could be conducted salus ti\n",
+ "us secretly set out with a small force of handpicked soldiers who had travelled with him from rome\n",
+ "with a devious plan to steal the codex from right under cal gac us noses a lust i us was a very\n",
+ "unpleasant man but he was widely read and knew of the hebrew tale of gideon he set his guard at key\n",
+ "points around the perimeter of the caledonian camp and in the depths of night when all men are at\n",
+ "their lowest ebb they rose as one breaking cover and making noise like a much larger army in the\n",
+ "confusions a lust i uss lieutenant stole into the camp and made away with the codex returning it to\n",
+ "salus ti us who remained throughout at a safe distance perhaps salus tiu scared nothing for the fate\n",
+ "of the ixth legion perhaps its destruction was part of domitian s planned revenge or perhaps it was\n",
+ "just a diversionary tactic to have them camped at s trac athro but the outcome was the same roused\n",
+ "by the surprise invasion of their camp the caledonian warriors launched a massive assault ons trac\n",
+ "athro whatever his motivation in an act of the greatest treachery salus ti us abandoned the ixth\n",
+ "legion to oblivion and set out south for the fortified port at car riden where he intended to escape\n",
+ "by sea from britannia with the codex he sent a despatch to ca to ordering him to retreat with all\n",
+ "able men to car riden raze inch tuth il to the ground and leave none of the weak or wounded alive in\n",
+ "order to provide nothing of value to the enemy salus ti us and his guard must have thought they\n",
+ "would be safe but once more a proud son of rome had grossly underestimated cal gac us realising\n",
+ "quickly that the codex was los the set out to recover it marching his men double time in pursuit of\n",
+ "the fleeing salus ti us and so at car ride nsa lust i us regrouped with his trusty guard and the\n",
+ "remaining cohorts from inch tuthill ed by the steadfast marcus fidel i usca to it was not long\n",
+ "before the pursuing caledonian force arrived before the gates of car riden and laid siege with their\n",
+ "backs to water the roman force was trapped their safety lay in a refuge far over these a and it is\n",
+ "fitting that the ending of my story will lie buried safely in their refuge at novio magus bat av\n",
+ "orum\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(lcat(tpack(segment(vigenere_decipher(sanitise(scbz), 'scytale')))))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 228,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "4423"
+ ]
+ },
+ "execution_count": 228,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "open('7b.plaintext', 'w').write(lcat(tpack(segment(vigenere_decipher(sanitise(scbz), 'scytale')))))"
+ ]
+ },
+ {
+ "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.5.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}