Done challenge 7
authorNeil Smith <neil.git@njae.me.uk>
Thu, 30 Nov 2017 21:44:33 +0000 (21:44 +0000)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 30 Nov 2017 21:44:33 +0000 (21:44 +0000)
2017/2017-challenge7.ipynb [new file with mode: 0644]
2017/7a.ciphertext [new file with mode: 0644]
2017/7a.plaintext [new file with mode: 0644]
2017/7b.ciphertext [new file with mode: 0644]
2017/7b.plaintext [new file with mode: 0644]

diff --git a/2017/2017-challenge7.ipynb b/2017/2017-challenge7.ipynb
new file mode 100644 (file)
index 0000000..318462d
--- /dev/null
@@ -0,0 +1,1311 @@
+{
+ "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
+}
diff --git a/2017/7a.ciphertext b/2017/7a.ciphertext
new file mode 100644 (file)
index 0000000..384930a
--- /dev/null
@@ -0,0 +1 @@
+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
\ No newline at end of file
diff --git a/2017/7a.plaintext b/2017/7a.plaintext
new file mode 100644 (file)
index 0000000..f11459d
--- /dev/null
@@ -0,0 +1,15 @@
+well that was a surprise and quite a relief as i said before no one really knows where the hanging
+gardens of babylon were located and i dont think we would have had a chance of finding the next
+chapter if that was where it was buried but it seems that tacitus had a better idea the babylonian
+goddess of love and war was ishtar and the ishtar gate from babylon was one of the original seven
+wonders of the world it was later replaced by the lighthouse of alexandria so i am not sure why
+tacitus used both but maybe because he didnt know where the hanging gardens were either or maybe he
+just wanted to confuse the uninitiated and to add an extra layer of secrecy via confusion abit like
+he does by piling up ciphers in these later chapters anyway we are in luck the ishtar gate now lives
+in the pergamon museum in berlin and i happen to have a pass to the full collection i am not sure
+how they will feel about us dismantling it to try to find chapter seven but if we explain what is in
+it i suspect the curators curiosity will overcome his natural protectiveness perhaps there we will
+finally unlock the secret of the ixth legion that leaves the question of how we deal with midas and
+maryam has a clever idea we should let the collector deal with them the russian mafia can be pretty
+ruthless if they feel betrayed and she has suggested away we might make the thieves fallout it is a
+cunning plan and i think i can help
\ No newline at end of file
diff --git a/2017/7b.ciphertext b/2017/7b.ciphertext
new file mode 100644 (file)
index 0000000..e1c6ab3
--- /dev/null
@@ -0,0 +1 @@
+OREOM CUFED VTMGJ ELEHG VYHDN VWGKS HMBCY LMIEX LRWFF WXBKF SZEAF KZPLR VSJUE ZTTMC APOAT SJUSP EMCQF LFIXM GSEAT GRTOI EYYMV JVEUA UGLIO XWFTW GFEBF QLFCE PLTDW ZAAEO AJFIM MUARE BTYPC TPTBR GAASR TYFDL OEARG LLXNE EPWEO RPPPZ YZAEF QPRLO NYFLM DDTDR SRWMW PUOEL EPDIE RWAXG GUYTL PQGKT ZCGLP QLOAF CHZRS OTMEK MSCAR USEEA ABHZW PFLRU ZMEDM CGYME HXYQS RGALD AAPYD MAUOQ CADBJ JISMB TNLIQ GXYUK EJATC FSRSE HMVSI ENXCG GETEY UNWMD HXZPJ OTEEY VXWTE GCJSI TCXLU AVPUT CPZPD NZCHL SLDVY QLPCE AUVJV TVVYE TSPEH WTASP PEYKM EGUMF VAZTT ZQESY OHERX VXQFB RTZMP CLKPL SDEAM KLISL HBGMS ZDGRM FMCPX LNZCE DTRJL YLOKS HSWPM TQUAL NAASE LMXBX QVWPD ABJUM XCUWK ILMED LYEWE LOHNP VJCBM CTSHH EDRTG WPRRY GWIET TLHJP TEADP SXXKV ECYTR CDQPT KUPFH OCUMC SGPEA CKLMM NWGJJ GQGHM FMWLE TMHEV GITQC WSJAL SGHVS CYJKD IERLG GFVOO FPEAW YTGBP UPZSX MKPMQ RKMQX MEEHJ JYMAE HCFAM DSXLC SIDAX CWOOY EBGPS PYOPY WGIFC GGPSP SOXQP GEYTV CKAUC ETQTJ EREVA QDMNO MAKKW EYXDN LGSPG UQDES NZPVV XFHHS KLROH XPGZI YRGBC KWEEM PCLZZ TTCOW SCUWG QOIYR GYCMM PPYYR YXWEH MGDLD SAUGV ELIBR KJLHD BHVVI CAHQU VHDIK CKSGY EBMCV MCTBY GUVSR VCVKY DNPCF WIHFG FTQWO RKAPE RANAK CJXPA KECAW LAKFW SYFTB CPSXZ TZYWW HRTWA CMGZF YRJFT PTLDK SIZAT YUQGP AMYWM ADUMN PFMEE GMPEI WRKCU SRZRM FNKSP EHGUK SZETG GFHLE ULJVI DTHLQ SEPCX GVLYW OAMFN HCNZS GKMSR AMJDJ YEWPF DVLLK GESSD EMMOF IWINF KMEED NPRZY LTTAU FLMTL SNLWY RNEQG VPHLP PKMTS XMTLH DLKDT SMTTW KAAIW ENMIS _RUFX QCAUI SFCBT YCXXL ETLPA HTAGZ TLVRO MCGZS ZRYMV LWOMN MXQIY DAPFJ AWALG NWIST XGJSJ PHLQQ FSEOM FNLWS CTBKS AEDVR RGSZA MLQFL CUBCK MMWWJ GCUXS LBRVS WDDUQ JUHTO EEKUJ QNEQU YXEDG CTXIY NVETV INULQ UMWXI MYQJG LAADN FINSA JVLMW RMCQS INDTR NJMLR HGEQP TCLLV QSZRN CKVAP VPJCJ XCFBR VGRLS PSEFQ DFGUK DENSM JUKWT EGQCZ INNKP KGYYE BGGCG YRAMG WELTH RGJOY RDFDM EFEMR NWHOE ATYES SOGYQ GXNUL GCFEM AEYYZ XRHBB RSXTO TGRLX TEXRN WCDEV LPWQC MXQNK XDNVB YZHFI EQOLL LIXNU SXZAA JRKWT PWYPN VASWG VLXXS MRVSE DHKTQ JLOWK ACSXL OOKVS JPTXS CFMRO HCQJV OTWPV LTLRB RGFTZ RZPVD QLNGF JFIYE KCGWS ZOXCC MMOAN CFWGL SHEAW XREGI VVPDT OYIFI YIXLU FGPSX CJKVS IHDEA CPTLG QFKPR VLTAJ POBBK LVERF ATLEL ETRCK REIRU GVCTG OSX_A GQMSP RTYAW EFSKL QZPDN BBRXX GPECJ AGYHX GCJZD CGQKS CMSKG YJKYT XMIAK YCOYR LISDG CISST FBPEF LEOMQ KWEPS TMPSV EEACP JQNHM PEAIW EBMVS MPUGF MSIPN XRFSN EYMMQ GBYIM RCJLX UPRKA MNGPY TDWDO GINVE DTAFC ASYOV RESZE ATFIG SLTLG GGIPH ZQVKE WSAYQ EGZVH PJSWC KZFEF WPEGQ QSRZI ZLGZI ZNMMM XXSTL YKAXZ AWRGF LEHNQ HOGYD UGGGE TCXRR USWTK YGUKQ EGQKL RPIEP QFHPI VCEDW EOAJQ HWCAX GHEEF TEBOM EDANT RFYDY GMGSM PSTMT ZQQLT YJZKY NMMDJ SLOWE NMKJC BSUWX EAFYV WVEUP YJGWD PLRTZ VEEXC KLSLO GLGHW UIHYQ ZTEHM AUEIP ITDEW SLSAQ UGGHE HGPLE CRLZG PMMNM SVLTN EXCQW JTAAV VSGOH XUNWV CCBCF SIHWW GTNXQ TGJUK QGGRZ DWTZM KSUWE LGERG GIZEK FFLTE FZRFS REGWG VVIYH KFNLE XFNGQ TXDAB AXGKQ DECJT SEAXY JXCQR ALHYL YSBZU AVPIL M_HZN PJAZY VFGAX MOWPG LMZSW JQEIZ ETFPS MTMGL VWLLI TSISM XWVYA ZSZCG JVSHZ EGYTJ IZFFP PXRZN MYKWI QUTSE VMWUN AUMSP AWYEW YPIMF NZHGI GPHKV TDXJD VKLOE GPGLD IMKHD LLHAR QAIDA KQPUY SNEMG WMFEA CVDLL EXPPM WQAAF OASCS HDHZX FANLW VWPIM FGEEE EZSKL WZNNC VZEYT XYKMH DDVLA GPEAW TGBHS EICTA ISTEY GWVWO AEFWV CSXMK CGEUG QHDEP WMCEF ISPMY GLEWN HVEVH YEVDG TECOV RWKPF AYDKG WOLMP GVWZT XPPDR WSXJV LACDY ZNVWR TBMGW XPNGC UZELH PZQFO GMGGE WMZOL JPGSX ARFZF XDHBP WSXPS BCKLI TGKRT FVXSX LGAYG NVFGW VCHHR GVWDS MYEFV WELQP SLCTH YJLIJ TTBVG PLOMF KGEYH GCDJX HEAYV SITTB YPJES LZYXG IZAGR KZZZE NYIMI SWXSO JRPOG RFUPB YAVUL VCCBM KMSWS BQTKM CWLWC JMZOM JJVET SMRGZ YWAXC TSGPA ZRCOL YWICG AYZEW GVWKE LNYPJ EZBK_ THIGR SANUT LVZSX HZJTF VPIBP CTWET BENSR AEZFT APLLL PPLES TLRGO WLIHF ELROT RCAUR FAXDR YVEHE YTXME LLPEN COSTG EHHYI KCDEJ PAMUG JIWAB GYWVL QRJVA WQEGB KWEFO FRGMX PFHLU FXDAM RUFIZ LFEZN XEETF ISFOA MRPOW EEBNP AKXLH RQAXW SMQVL MZRKR RAIGE GLQKG LEXCG KSSME GHSSZ ABUVN LNHHW WVMXR TMQCI EEGQT SWHTB KFSSE TKRGW VESVR GFXLL HCGKX CSGNJ LILFM FYLFF OWQGF QFOXQ GQXDO AANOX WHHUG HWSXB BIGYH RXKJA IVTKC GWYVN NNVZH NDWMV DVPEM QGAIL ODFTF RYTBY NLTOW XPKGX ZNHRH SVLUW LJGBT HLSYL MADZP VKILT TKFSS PMAPD MITHF YKJEO ITQVS LTNVC GSWTN MFPAR FHXDT JAPDL WQSMN EWAVJ QCTUR KRXER GCHSY WOHBK SXXSG SULXZ SMMQG LDDBA WAYEE PRQWM SSNKT XILUH PCMST TZLGF VXUXC HJHNW EDGAI YAWCV SRTEA ACWJL PBRPY ZDIMF GGSWR YRGLQ LU
\ No newline at end of file
diff --git a/2017/7b.plaintext b/2017/7b.plaintext
new file mode 100644 (file)
index 0000000..9846b7c
--- /dev/null
@@ -0,0 +1,46 @@
+with hindsight an opportunity for peace was thrown away cal gac us may have been a traitor but he
+was born a roman and had forged the local tribes into an organised and disciplined force it may have
+been possible to treat with him bringing caledonia within the empire in exchange for the
+governorship of caledonia but salus ti us was a greedy and ambitious man for whom victory was
+everything he had no wish to share caledonia or glory with cal gac us and thus conceived a plan to
+repay the treachery of the caledon ii in full he made a great fanfare of pushing his forces into
+northern caledonia to the remote for to finch tuth ilsa lust i us in secret had conceived a sly and
+audacious plan ca to was instructed to proceed with an expeditionary force from e bora cum to the
+frontier fort at inch tuth il where he would relieve the ii legion a diu trix pia fidelis who were
+required in dacia he quickly established the legion in a state of battle readiness and was joined
+thereby salus ti us who took command of the ix legion humiliating the faithful ca to in front of his
+own mensa lust i us was no strategist but in tactics and cunning he knew no parallel from the
+legions extensive scouting network he had learned that cal gac us had established his headquarters
+in the mountains west of s trac athro the marching camp leaving ca to in charge of a smallholding
+force of two cohorts at inch tuth ilsa lust i us ostentatiously led the rest of the ix legion to s
+trac athro he setup camp and laid waste to the villages around him in an act of gross provocation
+and cruelty he emulated his hero crassus knowing that the many caledon ii who suffered a gruesome
+end on his caledonian way were not involved with cal gac us and his revolt they were just fodder in
+his attempt to provoke a confrontation a she knew they must the caledonian armies mustered for a
+final showdown with the legion and marched on stra cath rosa lust i us set his forces with picket
+fences and traps but against the scale of the caledonian force there was little hope of success
+nonetheless with their pride at stake and accepting their fate the legionnaires of the ixth watched
+and waited to join battle undercover of darkness and before any skirmish could be conducted salus ti
+us secretly set out with a small force of handpicked soldiers who had travelled with him from rome
+with a devious plan to steal the codex from right under cal gac us noses a lust i us was a very
+unpleasant man but he was widely read and knew of the hebrew tale of gideon he set his guard at key
+points around the perimeter of the caledonian camp and in the depths of night when all men are at
+their lowest ebb they rose as one breaking cover and making noise like a much larger army in the
+confusions a lust i uss lieutenant stole into the camp and made away with the codex returning it to
+salus ti us who remained throughout at a safe distance perhaps salus tiu scared nothing for the fate
+of the ixth legion perhaps its destruction was part of domitian s planned revenge or perhaps it was
+just a diversionary tactic to have them camped at s trac athro but the outcome was the same roused
+by the surprise invasion of their camp the caledonian warriors launched a massive assault ons trac
+athro whatever his motivation in an act of the greatest treachery salus ti us abandoned the ixth
+legion to oblivion and set out south for the fortified port at car riden where he intended to escape
+by sea from britannia with the codex he sent a despatch to ca to ordering him to retreat with all
+able men to car riden raze inch tuth il to the ground and leave none of the weak or wounded alive in
+order to provide nothing of value to the enemy salus ti us and his guard must have thought they
+would be safe but once more a proud son of rome had grossly underestimated cal gac us realising
+quickly that the codex was los the set out to recover it marching his men double time in pursuit of
+the fleeing salus ti us and so at car ride nsa lust i us regrouped with his trusty guard and the
+remaining cohorts from inch tuthill ed by the steadfast marcus fidel i usca to it was not long
+before the pursuing caledonian force arrived before the gates of car riden and laid siege with their
+backs to water the roman force was trapped their safety lay in a refuge far over these a and it is
+fitting that the ending of my story will lie buried safely in their refuge at novio magus bat av
+orum
\ No newline at end of file