Added development files
authorNeil Smith <neil.git@njae.me.uk>
Fri, 7 Mar 2014 04:16:45 +0000 (23:16 -0500)
committerNeil Smith <neil.git@njae.me.uk>
Fri, 7 Mar 2014 04:16:45 +0000 (23:16 -0500)
14 files changed:
caesar_break_parameter_trials.csv [new file with mode: 0644]
challenge6.ipynb [new file with mode: 0644]
challenge7.ipynb [new file with mode: 0644]
cipher.py [new file with mode: 0644]
cipher.sublime-project [new file with mode: 0644]
cipherbreak.py [new file with mode: 0644]
find_best_caesar_break_parameters.py [new file with mode: 0644]
find_wikipedia_titles.py [new file with mode: 0644]
language_models.py [new file with mode: 0644]
lettercount.py [new file with mode: 0644]
make-cracking-dictionary.py [new file with mode: 0644]
norms.py [new file with mode: 0644]
segment.py [new file with mode: 0644]
unknown-word-probability-investigation.ipynb [new file with mode: 0644]

diff --git a/caesar_break_parameter_trials.csv b/caesar_break_parameter_trials.csv
new file mode 100644 (file)
index 0000000..6f71f07
--- /dev/null
@@ -0,0 +1,93 @@
+,message_length
+scoring, 300, 100, 50, 30, 20, 10, 5
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+Pletters, 0.9994, 0.9994, 0.9994, 0.9966, 0.9778, 0.8174, 0.4712
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + euclidean_scaled, 0.9996, 0.9996, 0.9974, 0.9836, 0.9356, 0.7124, 0.4218
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+cosine_distance + normalised, 0.9994, 0.9996, 0.998, 0.9836, 0.934, 0.7186, 0.4402
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + euclidean_scaled, 0.9996, 0.9996, 0.99, 0.9506, 0.8892, 0.6562, 0.4368
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+geometric_mean + normalised, 0.9996, 0.9992, 0.9902, 0.9222, 0.9408, 0.7062, 0.4568
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + euclidean_scaled, 0.4688, 0.5122, 0.6894, 0.5948, 0.5258, 0.4426, 0.3642
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+harmonic_mean + normalised, 0.8134, 0.8368, 0.7672, 0.2674, 0.8608, 0.6736, 0.453
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + euclidean_scaled, 0.9998, 0.9994, 0.9984, 0.9904, 0.9502, 0.7558, 0.4348
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l1 + normalised, 0.9998, 0.9998, 0.9986, 0.9882, 0.955, 0.7252, 0.4432
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + euclidean_scaled, 0.9996, 0.9988, 0.9992, 0.9786, 0.9368, 0.712, 0.4336
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l2 + normalised, 0.9998, 0.999, 0.998, 0.9818, 0.933, 0.709, 0.4356
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + euclidean_scaled, 0.9996, 0.999, 0.996, 0.9684, 0.8934, 0.6282, 0.4084
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
+l3 + normalised, 1.0, 0.9986, 0.9932, 0.963, 0.8696, 0.594, 0.4122
diff --git a/challenge6.ipynb b/challenge6.ipynb
new file mode 100644 (file)
index 0000000..ca4e493
--- /dev/null
@@ -0,0 +1,1141 @@
+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%matplotlib inline\n",
+      "import matplotlib.pyplot as plt\n",
+      "\n",
+      "from cipherbreak import *\n",
+      "with open('2013/mona-lisa-words.txt') as f:\n",
+      "    mlwords = [line.rstrip() for line in f]\n",
+      "mltrans = collections.defaultdict(list)\n",
+      "for word in mlwords:\n",
+      "    mltrans[transpositions_of(word)] += [word]\n",
+      "c6a = open('2013/6a.ciphertext').read()\n",
+      "c6b = open('2013/6b.ciphertext').read()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c1a = open('2013/1a.ciphertext').read()\n",
+      "c1b = open('2013/1b.ciphertext').read()\n",
+      "c2a = open('2013/2a.ciphertext').read()\n",
+      "c2b = open('2013/2b.ciphertext').read()\n",
+      "c3a = open('2013/3a.ciphertext').read()\n",
+      "c3b = open('2013/3b.ciphertext').read()\n",
+      "c4a = open('2013/4a.ciphertext').read()\n",
+      "c4b = open('2013/4b.ciphertext').read()\n",
+      "c5a = open('2013/5a.ciphertext').read()\n",
+      "c5b = open('2013/5b.ciphertext').read()\n",
+      "\n",
+      "p1a = caesar_decipher(c1a, 8)\n",
+      "p1b = caesar_decipher(c1b, 14)\n",
+      "p2a = affine_decipher(c2a, 3, 3, True)\n",
+      "p2b = caesar_decipher(c2b, 6)\n",
+      "p3a = affine_decipher(c3a, 7, 8, True)\n",
+      "p3b = keyword_decipher(c3b, 'louvigny', 2)\n",
+      "p4a = keyword_decipher(c4a, 'montal', 2)\n",
+      "p4b = keyword_decipher(c4b, 'salvation', 2)\n",
+      "p5a = keyword_decipher(c5a, 'alfredo', 2)\n",
+      "p5b = vigenere_decipher(sanitise(c5b), 'florence')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(frequencies(sanitise(c6a)))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stderr",
+       "text": [
+        "/usr/local/lib/python3.3/dist-packages/matplotlib/figure.py:372: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+        "  \"matplotlib is currently using a non-GUI backend, \"\n"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nTSKWQQ011FATHzEH0Y4dO3TVVVcpLy9PvXv31m233aaXXnqpK3tLE8EE1CRiGdRQQw018RFzEB05\nckRDhw5t/XzIkCE6cuRIlzQFAOg+Yg6ic6MvAADoJCdGf/3rX50ZM2a0fv7www87gUDggmnGjh3r\n6NxYQV68ePHi1c1fY8eOvWiexHwfUVNTk0aMGKFNmzbpy1/+siZNmqTVq1dr5MiRscwOANBN9Yq5\nsFcv/fKXv9SMGTPU3Nysb3zjG4QQAKDD4vpkBQAAouHJCkmitrZWRUVFCV9uVVWVHnvssbjNf+XK\nlSosLNT8+fPjMv/OrLepU6cmpK5///4xLQfxdezYMT311FOm24AIom4v3qMfn3rqKW3cuFG/+93v\n4rqcWGzbti0hdYwwjZ3jOHF7XmVDQ4OefPLJuMwbHUMQxcmcOXM0YcIEjR49Ws8++6yrmqamJt15\n550qLCzUvHnzdPr06ag1L7zwgsaOHavi4mJ97Wtfc7Wcn/70pxoxYoRKSkr03nvvuap58cUXNXny\nZHm9Xt17771qaWmJWnPvvffq/fff1w033KBf/OIXrpbz4x//WAUFBSopKdFXv/pVV0drzc3Nuuee\nezR69GjNmDFDZ86ccbWsWI9U4nGEU1tbq4KCAt11110aMWKE7rjjDr322muaOnWq8vPz9be//a3d\n2pEjR3Z4HfzsZz9TUVGRioqKtGLFCtc9dmQb/fy25vb7WVtbqxEjRsjv96uoqEiHDx+OWnPy5End\ndNNNKi4uVlFRkdasWRO1ZvHixfrXv/4lr9eryspKV319/uh7+fLleuihh9qtWbJkyQVhF+0MxKOP\nPqrHH39cknT//fertLRUkrR582bdeeedbdYtXbr0gu/hgw8+qJUrV7bb269+9St5vV55vV4NGzZM\n1113XbvTx1Wsw7fRvnA47DiO45w6dcoZPXq08/HHH7c7/cGDBx3Lspw33njDcRzHWbBggbN8+fJ2\na9555x0nPz+/dd7nl9met956yykqKnJOnz7tHD9+3Lnqqqucxx57rN2affv2OTNnznSampocx3Gc\n++67z3nhhReiLstxHCcvLy/qez9vx44dTnFxsXP27FmnsbHRGT58eNTeDh486PTq1cvZu3ev4ziO\nU1FR4bz44ouulte/f39X03W2zs3059/HO++847S0tDjjx493FixY4DiO47z00kvO7Nmzo9Z2ZB2c\n3w5OnTrlnDhxwhk1apSze/fuqD12ZBuNZVs7v5wePXo4b775ZtRpz1u7dq2zcOHC1s+PHTsWtaa2\nttYZPXq062UcPHjwgumXL1/uVFVVtVuze/duZ9q0aa2fFxYWOocPH25z+u3btzvz5s1zHMdxrrnm\nGmfy5MnOp59+6lRVVTnPPPNMm3W1tbXOuHHjHMdxnObmZufKK690tT9wHMf59NNPnZKSEmfdunWu\npo8HjojiZMWKFSouLtaUKVN0+PBh/eMf/4haM3ToUE2ZMkWSdOedd2rr1q3tTr9582ZVVFQoK+vc\n33XJzMyMuozXX39dc+fOVZ8+fZSRkaFZs2ZFPfWxadMm7dy5UxMmTJDX69XmzZt18ODBqMvqqG3b\ntmn27Nm65JJL1L9/f82cOdPVaZlhw4ZpzJgxkqTx48ertra2y3tLhGHDhmnUqFGyLEujRo3S9ddf\nL0kaPXp01PfU0XWwdetWzZ07V3379lW/fv00d+5cvf7661F77Mg2Gsu2dt4VV1yhSZMmuZpWksaM\nGaMNGzZo8eLF2rp1qzweT9Qat710RnFxsT788EPV1dVp7969yszM1ODBg9ucfty4cdq5c6caGxvV\np08fTZkyRW+99Za2bt2qkpKSNuuuuOIKZWdna8+ePXrttdc0btw4V/sDSfr2t7+t0tJS3XTTTR1+\nf10l5uHbaFswGNSmTZu0fft29enTR9OnT9fZs2ej1n3+WoLT+rdD2p++oz9M/1vjtt7v9+vhhx/u\n0LI6KtbevvSlL7V+3LNnT1enNJPR599Hjx49dMkll7R+3NTU5LrWzTq42Lp2cy2rI9torN9PSerX\nr5/raSVp+PDh2r17t1555RV9//vfV2lpqX7wgx90aB7R9OrV64JT0m63s3nz5mnt2rWqr6/Xbbfd\n1u60vXv31rBhw/Tcc8/p6quv1pgxY7R582b985//VEFBQbu1d999t1atWqVQKKQFCxa46u25557T\nBx98YPxaGUdEcXD8+HFlZmaqT58+2r9/v7Zv3+6q7tChQ63T/v73v2/3NyBJuu666/THP/5R4XBY\nklr/bc+1116r6upqnTlzRo2NjVq3bl3UHVBpaanWrl2rjz76qHU5hw4dcvOWOmTq1Kl6+eWXdfbs\nWZ04cUKvvPIKF/rjpKSkRNXV1Tp9+rROnjyp6urqqNub1LFtNJZtLVZ1dXXq06eP7rjjDn3ve9/T\nrl27otZkZGSosbHR9TJs29aHH36ocDiss2fPat26da7qbr31Vq1evVpr167VvHnzok5fUlKi5cuX\na9q0aSopKdHTTz+tcePGRa2bM2eO1q9fr7feekszZsyIOv3OnTv12GOPJcVAIo6I4uCGG27Q008/\nrcLCQo0YMaL1VEZ7LMvSiBEj9MQTT2jBggUaNWqU7rvvvnZrCgsL9eCDD2ratGnq2bOnxo0bp9/+\n9rft1ni9Xt16660aO3ascnJyXJ3+GDlypH7yk5+ovLxcLS0t6t27t5588kn93//9n6v35daECRM0\na9YsjRkzRrZtq6ioSJdddlmHl+F2mbHuFDtaF2s/n//czdFxR5bp9Xr19a9/vfX7v3DhQo0dOzZq\njx3ZRv93W5s4caLro6KOruO3335bDzzwQOuRpJth2dnZ2Zo6daqKiop04403Rv2bar1799YPf/hD\nTZo0SYMHD1ZhYaGrPgsLC3XixAkNGTJEtm1Hnb6kpEQPP/ywpkyZor59+6pv376ufkno3bu3rrvu\nOmVmZrrq64knnlBDQ4OmT58uSZo4caKeeeaZqHXxwA2tSConT55Uv379dOrUKU2bNk3PPvusiouL\nTbfV6uOPP07p61CdUVtbq5kzZ+rtt9+Oqf6hhx5S//799d3vfreLO4MktbS0aPz48Vq7dq2uvPJK\n0+10CKfmkFTuueceeb1ejR8/XrfccktShdB//vMfXX311XrggQdMt2JMZ0+tcao1Pvbt26fhw4fr\n+uuvT7kQkjgiAgAYxhERAMAogggAYBRBBAAwiiACABhFEAEAjCKIAABG/T+xw3Fhb8rTYQAAAABJ\nRU5ErkJggg==\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeb9980c>"
+       ]
+      }
+     ],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6af = frequencies(sanitise(c6a))\n",
+      "plot_frequency_histogram(c6af, sort_key=lambda l: c6af[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xae9bdf4c>"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(normalised_english_counts, sort_key=lambda l: normalised_english_counts[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAawAAAEkCAYAAABzKwUZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHx5JREFUeJzt3X9QVXX+x/HXNSgLpNQxG++lUCF+KF5QkFHXpGwXtXTM\ntJg03aQidx23xmprahNn+1ZMuptGP7CZtXHb3B/ujrjKMq26d0ZLl0zsx6CNFtQFw9rMwF8E18/3\nD4siL+deEMSPPB8zZ7zH8z6f+zmHw33xOefce13GGCMAAM5zvbq7AwAAhIPAAgBYgcACAFiBwAIA\nWIHAAgBYgcACAFghZGCVlZUpKSlJCQkJKiwsPGP5vn37NGbMGPXu3VvLly8/Y3kgEFB6erqmTp3a\nOT0GAPRIEU4LA4GAFi5cqM2bN8vtdiszM1PTpk1TcnJyS03//v31/PPPa/369UHbWLFihVJSUtTQ\n0NC5PQcA9CiOI6zy8nLFx8crLi5OkZGRys3NVUlJSauaAQMGKCMjQ5GRkWesX1NTo9LSUt19993i\n/ckAgLPhGFi1tbWKjY1tmfd4PKqtrQ278QceeEDPPvusevXiUhkA4Ow4JonL5epwwxs3btSVV16p\n9PR0RlcAgLPmeA3L7XbL7/e3zPv9fnk8nrAafuutt7RhwwaVlpbq5MmTqq+v19y5c7VmzZpWdWlp\naXr33Xc70HUAwIXG6/Vqz549wRcaB01NTWbIkCGmqqrKNDY2Gq/XayorK4PWLlmyxCxbtizoMp/P\nZ26++eagy0J0wXpLliyh9jzqB7Xtrz1f+kFtx+tt4pQJjiOsiIgIFRUVKScnR4FAQHl5eUpOTlZx\ncbEkKT8/X3V1dcrMzFR9fb169eqlFStWqLKyUtHR0a3aOpvTiwAAOAaWJE2ePFmTJ09u9X/5+fkt\nj6+66qpWpw2DmTBhgiZMmNDBLgIAIF1UUFBQ0J0dWLp0qbq5C10uLi6O2vOoH9S2v/Z86Qe1Ha+3\nhVMmuL49Z9htXC4XdxECACQ5ZwJvkAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHA\nAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIA\nWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYIazAKisrU1JSkhISElRYWHjG8n37\n9mnMmDHq3bu3li9f3vL/fr9f119/vYYNG6bhw4dr5cqVnddzAECP4jLGGKeCQCCgxMREbd68WW63\nW5mZmVq7dq2Sk5Nbar744gt98sknWr9+vfr27avFixdLkurq6lRXV6e0tDQdPXpUo0aN0vr161ut\n63K5FKILAIAewikTQo6wysvLFR8fr7i4OEVGRio3N1clJSWtagYMGKCMjAxFRka2+v+rrrpKaWlp\nkqTo6GglJyfr4MGDHd0OAEAPFjKwamtrFRsb2zLv8XhUW1vb7ieqrq5WRUWFsrKy2r0uAPRUMTH9\n5HK5HKeYmH7d3c1zIiJUgcvlOusnOXr0qGbOnKkVK1YoOjr6rNsDgJ6ioeErSc6XTRoazv512gYh\nA8vtdsvv97fM+/1+eTyesJ+gqalJt956q+bMmaPp06cHrSkoKGh5nJ2drezs7LDbBwDYy+fzyefz\nhVUb8qaL5uZmJSYmasuWLRo0aJBGjx59xk0X3ykoKFCfPn1abrowxmjevHnq37+/fv/73wfvADdd\nAECbTp/lCvUaeeG8jjplQsjAkqR//etfuv/++xUIBJSXl6dHH31UxcXFkqT8/HzV1dUpMzNT9fX1\n6tWrl/r06aPKykrt2bNH1113nUaMGNFyavHpp5/WpEmTwuocAPR0BNYPloUTWF2JwAKAthFY3+OT\nLgAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAA\nAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABW\nILAAAFYgsAAAViCwAABWILAAAFYgsAAAVggZWGVlZUpKSlJCQoIKCwvPWL5v3z6NGTNGvXv31vLl\ny9u1LgAA4XIZY0xbCwOBgBITE7V582a53W5lZmZq7dq1Sk5Obqn54osv9Mknn2j9+vXq27evFi9e\nHPa6kuRyueTQBQDo0Vwul6RQr5EXzuuoUyY4jrDKy8sVHx+vuLg4RUZGKjc3VyUlJa1qBgwYoIyM\nDEVGRrZ7XQAAwuUYWLW1tYqNjW2Z93g8qq2tDavhs1kXAIAfcwys00PRjjmbdQEA+LEIp4Vut1t+\nv79l3u/3y+PxhNVwe9YtKChoeZydna3s7OywngMAYDefzyefzxdWreNNF83NzUpMTNSWLVs0aNAg\n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\n1CkzatQoM3/+fGOMMSUlJWb69OlntP/dz+47y5YtMwUFBY7bGM6x095js6qqyvTq1cv897//Ddn2\nunXrzD333NMy//XXXzu2GxERYd59911jjDG33Xabee2118669jvh7Atjvj8Ojh8/boYPH97msfTd\nfjt+/Lg5evSoGTZsmKmoqGiz3erq6lY/v7ZUVlaaqVOnmubmZmOMMQsWLDBr1qwJq+8XCkZYXWzR\nokWaOHGibrrppqDLt23bphkzZqh3797q06ePpk2b1qmnUp544gm98cYb2rVrlx5++GHH2s8//1zT\np0/X66+/7njNIC0tTZ9//rk+++wzvfvuu+rbt6/cbneb9bGxsRozZowkac6cOdq+fftZ17755pua\nPn26Lr74YkVHR2vq1Kmdtt+2bt2q2267Tf36nX6Td9++fYPWXXPNNerfv7/27NmjN954QyNHjgxa\n+91otaGhQb1799aYMWO0a9cubd++XePHjz+jfvDgwRo2bJhcLpeGDRumG2+8UZI0fPhwVVdXd8o2\nhqMjx+Y111yj0aNHh2x7xIgR+ve//61HHnlE27dvV0xMjGP94MGDNWLECEnSqFGjHPdDe2rbY8WK\nFUpLS9OYMWNUU1Oj/fv3B63bvn27ZsyYoUsvvVRRUVGaMWOGtm3b1ma74R63W7Zs0TvvvKOMjAyl\np6dr69atqqqq6tC22MrxtnacnVdffVV+v9/x/LTL5Wp1wHZmWEnS//73Px07dkyBQEAnTpzQZZdd\n1mbtFVdcoWuuuUbbtm1TUlKSY7uzZs3SunXrVFdXp9zcXMfaH177MMY4XgsJt7Yr99uP23Zy9913\na/Xq1Tp06JDmz58ftCYyMlKDBw/Wq6++qrFjx2rEiBHaunWrDhw4EHQ/X3LJJS2Pe/XqpYsvvrjl\ncXNz8xn1ERERrU4NOZ1GbY+O7OOoqKiw2k5ISFBFRYU2bdqkxx9/XBMnTtRvfvObNut/uE8uuugi\nx21sT224fD6ftmzZop07d6p37966/vrr1djYGLQ22H7ryDXDYObNm6ennnqqU9qyESOsLvLOO+9o\n+fLlIS/wX3fddVq/fr1OnjyphoYGbdy4sdMObun0e+WefPJJ3XHHHSHPj1988cX6xz/+oTVr1gR9\nk/cP3X777Vq7dq3WrVunWbNmOdZ++umn2rlzpyTp9ddfDzqqaG/tuHHj9M9//lONjY06evSoNm3a\n1Gn77YYbbtDf/vY3HT58WJJa/g3mlltuUVlZmXbt2qWcnJw268aPH69ly5ZpwoQJGj9+vF5++WWN\nHDmyU/o7cOBAff755zp8+LAaGxu1cePGTmm3K4/Nzz77TL1799bs2bP14IMPavfu3Z3Sblepr69X\n37591bt3b+3bt6/lGA1m/PjxWr9+vU6cOKFjx45p/fr1jsd8nz591NDQELIPEydO1Lp16/TFF19I\nOn1cfvrpp+3fGIsxwuoiL7zwgr766itdf/31kqTMzEytWrXqjLr09HTdfvvt8nq9uvLKK5WZmRn2\nX/ehXjzWrFmjSy65RLm5uTp16pTGjh0rn8+n7OzsNtu77LLLtHHjRv30pz9Vnz59dPPNNwetTUlJ\n0dGjR+XxeDRw4EDHPiYmJuqFF17Q/PnzNWzYMC1YsKDN+nBrMzIyNG3aNI0YMUIDBw5UamqqLr/8\n8rZ3hsK/yy0lJUWPPfaYJkyYoIsuukgjR47UH/7wh6C1kZGRuuGGG9S3b1/H9sePH6+nnnpKY8aM\n0aWXXqpLL720zRexH7fzw/lgzxEZGaknnnhCo0ePltvtVkpKSshtDWdf/PjYDOdUX7j7+P3339dD\nDz3UMoIMdVu30z45m9pwlkvSpEmT9PLLLyslJUWJiYktp62DSU9P189//vOW/XXPPffI6/W2Wd+/\nf3+NGzdOqampmjJlSpvfHZicnKwnn3xSP/vZz3Tq1ClFRkbqxRdf1NVXXx2y/xcK3jh8nlm6dKmi\no6O1ePFix7ovv/yyU8/Pnw+qq6s1depUvf/++2HVHzt2TFFRUTp+/LgmTJigV155RWlpaV3cy9ZO\nnTqlUaNGad26dRo6dOg5fW6gp+GU4Hko1F98Bw8e1NixY/XQQw+dox6dO+055XTvvfcqPT1do0aN\n0syZM895WFVWViohIUE33ngjYQWcA4ywAABWYIQFALACgQUAsAKBBQCwAoEFALACgQUAsAKBBQCw\nwv8DbMnA/BWkp54AAAAASUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaea606ec>"
+       ]
+      }
+     ],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6bf = frequencies(sanitise(c6b))\n",
+      "plot_frequency_histogram(c6bf, sort_key=lambda l: c6bf[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEkCAYAAAB6wKVjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGGFJREFUeJzt3XtQlNf9x/HPKhiNQIPpuLZgxYkIrqywanDUUFFEM01l\niKl4TWgwSWPb6bTNpTYXhTZVMtVONY25ODbBOtFap0Vrpg6N/jajtha1as1Qq22kEUSMQSOi8cbz\n+4OyUdkbuitn4f2a2RF2v3ues/us++E8l/PYLMuyBACAYbp1dAcAAPCGgAIAGImAAgAYiYACABiJ\ngAIAGImAAgAYyW9AHTt2TOPHj9fQoUOVlpam5cuXS5IaGhqUm5urwYMHa9KkSTpz5oznOYsXL1Zy\ncrJSU1NVUVER3t4DADotm7/zoE6cOKETJ04oIyND586d04gRI1ReXq633npLX/ziF/Xss8/q5Zdf\n1unTp1VaWqqqqirNmjVLu3fvVm1trSZOnKjDhw+rWzcGagCA9vGbHP369VNGRoYkKSYmRkOGDFFt\nba02bdqkwsJCSVJhYaHKy8slSRs3btTMmTMVHR2tpKQkDRo0SJWVlWF+CQCAzijooU11dbX27dun\nUaNGqb6+Xna7XZJkt9tVX18vSTp+/LgSExM9z0lMTFRtbW2IuwwA6AqCCqhz587poYce0rJlyxQb\nG3vdYzabTTabzedz/T0GAIAvUYEKLl++rIceekgPP/yw8vPzJbWMmk6cOKF+/fqprq5Offv2lSQl\nJCTo2LFjnufW1NQoISGhTZsZGRk6cOBAqF4DACCCpaena//+/W3u9zuCsixLc+fOlcPh0Pe//33P\n/Xl5eSorK5MklZWVeYIrLy9P69at06VLl3T06FEdOXJEmZmZbdo9cOCALMvqlLeFCxeGpTacbVPL\n+oj0WlP6YUJtJN58DVj8jqB27typNWvWaNiwYXK5XJJaDiOfP3++CgoKtGrVKiUlJWn9+vWSJIfD\noYKCAjkcDkVFRWnFihVs4gMA3BS/AXXfffepubnZ62Pvvfee1/ufe+45Pffcc7feMwBAl9a9uLi4\n+HYvtKSkRB2w2NsmKSkpLLXhbJva9tea0g9qzeqHCbWRxlcm+D1RN1xsNps6YLEAAAP5ygSmeAAA\nGImAAgAYiYACABiJgAIAw8TF9fHM0uPrFhfXp6O7GXYcJAEAhmk5fzTQd2Tn+R7lIAkAQEQhoAAA\nRiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYi\noAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAA\nAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABG\nIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKg\nAABGIqAAAEYKGFBFRUWy2+1yOp2e+4qLi5WYmCiXyyWXy6U//elPnscWL16s5ORkpaamqqKiIjy9\nBgB0ejbLsix/Bdu3b1dMTIweeeQRHTx4UJJUUlKi2NhY/fCHP7yutqqqSrNmzdLu3btVW1uriRMn\n6vDhw+rW7foctNlsCrBYAOiybDabpEDfkZ3ne9RXJgQcQWVlZSk+Pr7N/d4a27hxo2bOnKno6Ggl\nJSVp0KBBqqysvMkuAwC6spveB/XKK68oPT1dc+fO1ZkzZyRJx48fV2JioqcmMTFRtbW1t95LAECX\nE3UzT5o3b54WLFggSXrxxRf11FNPadWqVV5rW4aqbRUXF3t+zs7OVnZ29s10BQAQYdxut9xud8C6\nmwqovn37en5+7LHHNGXKFElSQkKCjh075nmspqZGCQkJXtu4NqAAAF3HjYOSkpISr3U3tYmvrq7O\n8/Mf/vAHzxF+eXl5WrdunS5duqSjR4/qyJEjyszMvJlFAECnEhfXRzabzectLq5PR3fROAFHUDNn\nztT777+vU6dOqX///iopKZHb7db+/ftls9k0cOBAvfHGG5Ikh8OhgoICORwORUVFacWKFT438QFA\nV9LYeFr+jsxrbOS78kYBDzMPy0I5zBxAFxP40PHPvxc5zLwFM0kAAIxEQAEAjERAAQCMREABAIxE\nQAEAjERAAQCMREABAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCMREAB\nAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCM\nREABAIxEQAEAjERAAQCMREABAIxEQAEAjERAAQCMREABwE2Ii+sjm83m9xYX16ejuxnRbJZlWbd9\noTabOmCxABAyNptNUqDvsc+/6wLXt6f2+vpI5ysTGEEBAIxEQAEAjERAAQCMREABAIxEQAEAjERA\nAQCMREABAIxEQAEAjERAAcD/MDuEWZhJAgD+pz0zODCTROgwkwQAIKIQUAA6NTbbRS4CCkDEaU/o\nNDaeVsvmMt+3lhqYhn1QACJOuPYVsQ+qY7APCoDR2BSHG0V1dAcAQLp2U5y/Gtvt6QyMwAgKAGAk\nAgoAYCQCCgBgJAIKAGAkAgoAYKSAAVVUVCS73S6n0+m5r6GhQbm5uRo8eLAmTZqkM2fOeB5bvHix\nkpOTlZqaqoqKivD0GgDQ6QUMqEcffVRbtmy57r7S0lLl5ubq8OHDysnJUWlpqSSpqqpKv/3tb1VV\nVaUtW7bo29/+tpqbm8PTcwBApxYwoLKyshQfH3/dfZs2bVJhYaEkqbCwUOXl5ZKkjRs3aubMmYqO\njlZSUpIGDRqkysrKMHQbANDZ3dQ+qPr6etntdkmS3W5XfX29JOn48eNKTEz01CUmJqq2tjYE3QQA\ndDW3PJNE6xQk/h73pri42PNzdna2srOzb7UrAIAI4Ha75Xa7A9bdVEDZ7XadOHFC/fr1U11dnfr2\n7StJSkhI0LFjxzx1NTU1SkhI8NrGtQEFAOg6bhyUlJSUeK27qU18eXl5KisrkySVlZUpPz/fc/+6\ndet06dIlHT16VEeOHFFmZubNLAIA0MUFHEHNnDlT77//vk6dOqX+/fvrJz/5iebPn6+CggKtWrVK\nSUlJWr9+vSTJ4XCooKBADodDUVFRWrFihd/NfwAA+ML1oAAYwYTrNnE9qI7B9aAAABGFgAIAGImA\nAgAYiYACEDZcxh23gku+AwgbLuOOW8EICgBgJAIKAGAkAgoAYCQCCgBgJAIKAGAkAgoAYCQCCgBg\nJAIKAGAkAgoAYCQCCgBgJAIKQLswvx5uF+biA9AuzK+H24URFADASAQUAMBIBBQAwEgEFADASAQU\nAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADA\nSAQUAMBIBBQALuMOI3HJdwBcxh1GYgQFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADAS\nAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASAQVEiPZe9TZQPVfI\nhelslmX5v4xmOBZqs6kDFgtENJvNpkBXvZU+/78VuL49tZ/XU9v+Wil866Mz8JUJjKAAAEYioAAA\nRoq6lScnJSUpLi5O3bt3V3R0tCorK9XQ0KDp06frv//9r5KSkrR+/XrdddddoeovAKCLuKURlM1m\nk9vt1r59+1RZWSlJKi0tVW5urg4fPqycnByVlpaGpKMAgK7lljfx3bhja9OmTSosLJQkFRYWqry8\n/FYXAQDogm55BDVx4kSNHDlSK1eulCTV19fLbrdLkux2u+rr62+9lwCALueW9kHt3LlTX/rSl/Tx\nxx8rNzdXqamp1z3eer6FN8XFxZ6fs7OzlZ2dfStdAQBECLfbLbfbHbAuZOdBlZSUKCYmRitXrpTb\n7Va/fv1UV1en8ePH69ChQ9cvlPOgAEktJ9M2Np72WxMbG6+zZxuMOe+GWs6DCrWQnwd1/vx5NTY2\nSpKamppUUVEhp9OpvLw8lZWVSZLKysqUn59/s4sAOr2WcLL83gIFGNBZ3fQmvvr6ej344IOSpCtX\nrmj27NmaNGmSRo4cqYKCAq1atcpzmDkAAO3FVEdAB4rETUrUmrU+OgOmOgIARBQCCgBgJAIKAGAk\nAgoAYCQCCgBgJAIKCLH2XvkWgHe3NNURgLY+P/nWX433KcAAfI4RFADASAQUAMBIBBQAwEgEFADA\nSAQUAMBIBBQAwEgEFADASAQUuqz2nFDLybfA7ceJuuiy2nNCLSffArcfIygAgJEIKACAkQgoAICR\nCCgAgJEIKBiPo+2AromAQodoT5B8fgSd71tLTftqAZiNw8zRIThsG0AgjKAAAEYioAAARiKgAABG\nIqAAAEYioAAARiKgAABGIqAAAEYioAAARiKgAABGIqAAAEYioBAygebXY5JWAO3BXHwImUDz6zG3\nHoD2YAQFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFnwJNXcT0\nRQDCiamO4FOgqYtaapi+CEB4MIICABiJgAIAGImA6mLYrwQgUrAPqothvxKASMEICgBgJAIKAGAk\nAgoAYCQCCgBgJAIKAGCksATUli1blJqaquTkZL388svhWASuwaHjADqjkAfU1atX9d3vfldbtmxR\nVVWV1q5dq3/+85+hXoyx3G63z8faEyTtqf380PFrb/933e8tNT573Z5XSG3Y26a2/bXhbDvSajuP\n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\nSUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xae9b112c>"
+       ]
+      }
+     ],
+     "prompt_number": 7
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(c6bf)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nW7duVVVVldatW6d//etfoZ6Nwdxhqg3ntLtObfv+aLSmh9bWm13bccstXLXhnLb32s9PU7j+8Zcb\nfr9a0/4e3O7ga7uSkAdUZWWlhgwZoqSkJEVHR2vWrFnatGlTqGdjMHeYasM57a5Te+sfjRd08x8R\n3380WtNDa+vNru245Rau2nBOu/NrCagQqaur08CBAz2/JyYmqq6uLtSzAQB0cSEPKJuNM+8BoD1u\n3uRaUlLSPfdvWSH2t7/9zZo6darn98WLF1ulpaU31KSnp9+84ZYHDx48eHTTR3p6utc8sVmWZSmE\nLl++rJSUFG3btk1f/vKXlZmZqXXr1mnYsGGhnA0AoIsL+cVio6Ki9Ktf/UpTp07VlStXNH/+fMIJ\nANBqIR9BAQAQClxJohPU1NTI6XSGfT7FxcVatmxZyKa3YsUKORwOPfjggyGbZluWxfjx40Na35Ye\nYmJiWlWP1vnkk0/06quvdnYb6GQEVBcW6iMqX331Vb377rv6zW9+E9LpttauXbvCWh8Mjla9lWVZ\nCtUGmdOnT2vlypUhmRYiFwEVQvfff79Gjx6ttLQ0rVq1ym/t5cuXNW/ePDkcDs2YMUPnz5/3Wbtm\nzRqlp6crIyNDDz30kN/p/uxnP1NKSoqysrL073//22/t2rVrNWbMGLlcLj3++ONqaWnxWfv444/r\ngw8+0L333qtf/vKXfqcrST/96U+VmpqqrKwszZkzx+9I7sqVK3rssceUlpamqVOn6rPPPvM77daO\nXlpT/8EHH2jkyJHat29fq+Zxs5qaGqWmpurhhx9WSkqK5s6dq4qKCo0fP15Dhw7Vnj17bqkfNmxY\n0MvhF7/4hZxOp5xOp5YvXx5UL8Gub9evQ4G+u5qaGqWkpKiwsFBOp1O1tbVe65qbm3XfffcpIyND\nTqdTGzZs8NvzwoUL9d///lcul0s/+tGP/M7/+tHv0qVLVVJS4rX2xz/+8Q2h52sLw89//nO9/PLL\nkqQf/OAHysnJkSRt375d8+bNu6V+z549Sk9P14ULF9Tc3Ky0tDRVVVV57eGFF1644ft69tlntWLF\nCp+f7/XXX5fL5ZLL5dLgwYM1adIkn7VdUqgPM+/OGhsbLcuyrHPnzllpaWnWxx9/7LWuurrastls\n1l//+lfLsiyrqKjIWrp0qdfa999/3xo6dKhnWtfm4c3evXstp9NpnT9/3vr000+tIUOGWMuWLfNa\nW1VVZU2bNs26fPmyZVmWtWDBAmvNmjV+P19SUpLPz3S9yspKKyMjw7pw4YLV1NRkJScn++yjurra\nioqKsg4ePGhZlmUVFBRYa9eu9Tv9mJiYgD20pr66utpKS0uzDh8+bLlcLuuf//xnSKYZFRVlvf/+\n+1ZLS4s1atQoq6ioyLIsy9q0aZOVn5/vtT6Y5XDtez537px19uxZa/jw4db+/fv99hLs+taadeja\ntHv06GH9/e9/970wLMvauHGj9eijj3p+/+STT/zW19TUWGlpaX5rrs3/+rqlS5daxcXFXmv3799v\nTZgwwfO7w+Gwamtrb6nbvXu3NWPGDMuyLOuee+6xxowZY126dMkqLi623njjDa/Tfu6556wnn3zS\n+s53vnPLaTU3f66RI0dalmVZV65cse666y6//6avuXTpkpWVlWVt2bIlYG1XwggqhJYvX66MjAyN\nHTtWtbW1Onr0qM/agQMHauzYsZKkefPmaefOnV7rtm/froKCAvXrd/WkvPj4eJ/T3LFjh6ZPn67e\nvXsrNjZWeXl5Pje5bNu2Tfv27dPo0aPlcrm0fft2VVdXB/tR/dq1a5fy8/PVq1cvxcTEaNq0aX43\n/QwePFgjRoyQJI0aNUo1NTUh6aM1Tp48qfz8fL399tsh2z84ePBgDR8+XDabTcOHD9fkyZMlSWlp\naV4/Y7DLYefOnZo+fbr69Omjvn37avr06dqxY4ffXoJd31qzDl0zaNAgZWZm+q0ZMWKE/vznP2vh\nwoXauXOn4uLi/NYHmmdbZGRk6OTJk6qvr9fBgwcVHx+vhISEW+qujaCbmprUu3dvjR07Vnv37tXO\nnTuVlZXlddqLFi1SRUWF9u7dq6efftpnD4MGDdKdd96pAwcOqKKiQiNHjvT7b/qa733ve8rJydF9\n990X/AfuAkJ+mHl35Xa7tW3bNu3evVu9e/fWxIkTdeHCBZ/11+/DsCzL5z4Nm80W9D/Wm2sDva+w\nsFCLFy8Oatqt0do+brvtNs/PPXv29Lv5KVzuuOMODRo0SDt27FBqampIpnn95+rRo4d69erl+fny\n5ct+6/0tB2/LN9A+sbaub8Gse3379g1Yk5ycrP379+udd97Rc889p5ycHD3//PMB3xdIVFTUDZum\nA607M2bM0MaNG3XixAnNmjXLa010dLQGDx6st956S+PGjdOIESO0fft2/ec///G5bpw6dUrNzc26\ncuWKzp8/r9tvv91nD4888ojefPNNNTQ0qKioKOBnfOutt3Ts2LFuuU+OEVSIfPrpp4qPj1fv3r11\n+PBh7d6922/9hx9+6Kl5++23ff6f2aRJk/S73/1OjY2NkuT5rzdf/epXVV5ers8++0xNTU3asmWL\nzz9EOTk52rhxoz766CPPdD/88MOAnzMY48eP1x//+EdduHBBZ8+e1TvvvGP8QQW9evXS73//e61Z\ns0br1q3r7Hb8ysrKUnl5uc6fP6/m5maVl5f7XH+uCXZ9a8061Br19fXq3bu35s6dqyeffFL/+Mc/\n/NbHxsaqqakp4HTtdrtOnjypxsZGXbhwQVu2bPFbP3PmTK1bt04bN27UjBkzfNZlZWVp6dKlmjBh\ngrKysvTaa69p5MiRPuu/9a1v6cUXX9ScOXP87jOTru6r3rp1q/bu3aupU6f6rd23b5+WLVvW6Qcm\ndRZGUCFy77336rXXXpPD4VBKSopnc4o3NptNKSkpeuWVV1RUVKThw4drwYIFXmsdDoeeffZZTZgw\nQT179tTIkSP161//2muty+XSzJkzlZ6erv79+/vd7DJs2DC9+OKLmjJlilpaWhQdHa2VK1fqK1/5\nit++gzF69Gjl5eVpxIgRstvtcjqd+sIXvhD0dFszGghGMPU2m0233367tmzZotzcXMXGxurrX/96\nu6fp63dv7w92ObhcLn3zm9/0fL+PPvqo0tPT/fYS7Pp28zp09913BxxFBbMsDh06pKeeesozkgx0\nCPmdd96p8ePHy+l06mtf+5rP+8pFR0dr0aJFyszMVEJCghwOh99+HA6Hzp49q8TERNntdp91WVlZ\nWrx4scaOHas+ffqoT58+PkN9zZo1uu222zRr1iy1tLRo3Lhxcrvdys7O9tnzpEmTFB8fH3DZvfLK\nKzp9+rQmTpwoSbr77rv1xhtv+H1PV8KJugiL5uZm9e3bV+fOndOECRO0atUqZWRkdHgfH3/8caft\n1zJFTU2Npk2bpkOHDrX6vSUlJYqJidETTzwRhs66p5aWFo0aNUobN27UXXfd1dntGI1NfAiLxx57\nTC6XS6NGjdI3vvGNTgmn48ePa9y4cXrqqac6fN6mac9mOtM3z0aSqqoqJScna/LkyYRTEBhBAQCM\nxAgKAGAkAgoAYCQCCgBgJAIKAGAkAgoAYCQCCgBgpP8D+njZv7/d4VMAAAAASUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaea4c52c>"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(normalised_english_counts)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nMEAjR45s8cIJ6Uzo9OrVq+mii1DX5aKLrsVFFwDCiVMmOM6wIiIiVFhYqNzcXAUCAc2bN0/Jyckq\nKiqSJOXn5+vQoUPKzMxUbW2tevTooRUrVqiiokLR0dEtrgsAQHs4zrAuSAPMsLoUMywA4aTdl7UD\nABAuCCwAgBUILACAFQgsAIAVCCwAgBUILACAFQgsAIAVCCwAgBUILACAFQgsAIAVCCwAgBUILACA\nFQgsAIAVCCwAgBUILACAFQgsAGEnJqaPXC6X4y0mpk9Xt4kLjA9wvMjxAY4IR7wuL158gCMAwHoE\nFgDACgQWAMAKBBYAwAoEFgDACgQWAMAKBBYAwAoEFgDACgQWAMAKBBYAwAoEFgDACkEDq7S0VElJ\nSUpISNDSpUtbrFm4cKESEhLk9XpVXl7e9P1nnnlGQ4YMUVpamu68807V19efv84BABcVx8AKBAJa\nsGCBSktLVVFRobVr12rv3r3NakpKSnTgwAHt379fq1at0vz58yVJVVVVevXVV7V792598MEHCgQC\n+vOf/9x5IwEAdGuOgVVWVqb4+HjFxcUpMjJSeXl5Ki4ublazYcMGzZkzR5KUlZWlo0eP6vDhw4qJ\niVFkZKROnDihxsZGnThxQm63u/NGAgDo1hwDq6amRrGxsU3LHo9HNTU1IdX06dNHixYt0rXXXqsB\nAwboqquu0k033XSe2wcAXCwcA+vMZ9IE19Jnl3z88cd6/vnnVVVVpYMHD+rYsWP605/+1L4uAZyD\nDznExSbC6U632y2/39+07Pf75fF4HGuqq6vldrvl8/k0evRo9e3bV5I0bdo0vf3225o5c+Y5j1NQ\nUND0dU5OjnJyctozFuCiUlf3tYJ9yGFdXWi/dAJdxefzyefzhVZsHDQ0NJhBgwaZyspKU19fb7xe\nr6moqGhWs2nTJjNx4kRjjDE7duwwWVlZxhhjysvLzZAhQ8yJEyfM6dOnzezZs01hYeE5jxGkBXQy\nSUYyQW48R+GoOz933XlscOb0vDrOsCIiIlRYWKjc3FwFAgHNmzdPycnJKioqkiTl5+dr0qRJKikp\nUXx8vKKiorR69WpJUnp6umbPnq0RI0aoR48eGjZsmO677752JTAAAK7vEq3rGnC5WjwHZqOYmD7f\nHaZpXa9evVVbe+QCdRTcmfOUwfZ/93mOupPu/Nx157HBmVMmEFjnkY0/ZDb2jDO683PXnccGZ06Z\nwFszAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxA\nYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgwSoxMX3kcrkcbzExfbq6TQCdgMCC\nVerqvpZkHG9nauxEIAOtI7DQ5fhP+nvdPZCBjojo6gaA7/+TdqpxXZhmAIQtZlgAACsQWAAuCA79\noqM4JAjgguDQLzqKGRYAwAoEFgDACkEDq7S0VElJSUpISNDSpUtbrFm4cKESEhLk9XpVXl7e9P2j\nR49q+vTpSk5OVkpKinbu3Hn+OgcAXFQcAysQCGjBggUqLS1VRUWF1q5dq7179zarKSkp0YEDB7R/\n/36tWrVK8+fPb7rvV7/6lSZNmqS9e/fq/fffV3JycueMAgDQ7TkGVllZmeLj4xUXF6fIyEjl5eWp\nuLi4Wc2GDRs0Z84cSVJWVpaOHj2qw4cP65tvvtG2bds0d+5cSVJERISuvPLKThoGAKC7cwysmpoa\nxcbGNi17PB7V1NQEramurlZlZaX69eunu+++W8OGDdO9996rEydOnOf2AQAXC8fAcrlCu8TUmOaX\nqrpcLjU2Nmr37t36xS9+od27dysqKkrPPvts+zsFAFzUHP8Oy+12y+/3Ny37/X55PB7Hmurqarnd\nbhlj5PF4lJmZKUmaPn16q4FVUFDQ9HVOTo5ycnLaOg4AXSAmpk/Q9zbs1au3amuPXKCOYBufzyef\nzxdasXHQ0NBgBg0aZCorK019fb3xer2moqKiWc2mTZvMxIkTjTHG7Nixw2RlZTXdl52dbT766CNj\njDGLFy82jzzyyDmPEaQFq0gykglyC6/xhkPPbekhHPrtTLbti87qNxzGhq7h9Lw6zrAiIiJUWFio\n3NxcBQIBzZs3T8nJySoqKpIk5efna9KkSSopKVF8fLyioqK0evXqpvVfeOEFzZw5U99++60GDx7c\n7D4AANrC9V2idV0DLtc558BsdeacX7CxhNd4w6HntvQQDv12Jtv2RWf1Gw5jQ9dwygTe6QIAYAUC\nCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsA\nYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAF\n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\nrY7prLKyMpOenm7q6+tNXV2dSUhIaLWHyspKExERYd577z1jjDG33367ef311x23Hx0d7Xh/e9ap\nrKw0qampZt++fSYjI8O8//77Hdrm2XF9+OGH5vTp02b48OFm7ty5xhhjiouLzdSpU1tdJ5R9cfZ5\nPnHihDl27JgZMmSIKS8vb7WXUF9rbXn9nN12jx49zH//+99Wa85at26duffee5uWv/nmm1Zrq6qq\nTGpqatBtnu3hh7XLli0zBQUF59SVl5ebsWPHNi2npKSY6urqFre5c+dOM2PGDGOMMT/5yU9MVlaW\naWhoMAUFBWbVqlUtrvPEE0+Yhx56yPzyl79s8c95zqqqqjLDhg0zxhgTCATM4MGDHX+mjTGmoaHB\nZGdnm40bNzrWdUfMsDrRihUrlJ6erlGjRqm6ulr79+9vtTY2NlajRo2SJM2aNUvbt29vsW7r1q26\n/fbb1afPmT8U7N27d6vb3LZtm6ZNm6aePXuqV69emjJlSquHabZs2aJ3331XI0aMUEZGhrZu3arK\nyspQh9qqt956S1OnTtWll16q6OhoTZ482fFQ0cCBAzV06FBJ0vDhw1VVVdXhHtrjiy++0NSpU/XG\nG2+cl/OLAwcO1JAhQ+RyuTRkyBDddNNNkqTU1NRWxxjqvti+fbumTZumyy+/XFFRUZo2bZq2bdvW\nai+hvtba8vo567rrrtPIkSMdayRp6NCh+ve//61HH31U27dvV0xMTKu1wR6zPdLT0/XFF1/o888/\n13vvvafevXvL7Xa3WHt2hl1XV6eePXtq1KhR2rVrl7Zv367s7OwW13nyySf15ptvateuXXrkkUda\n7eO6665T3759tWfPHr355psaNmyY48+0dObNxsePH6+bb7459AF3E46XtaP9fD6ftmzZop07d6pn\nz54aN26c6uvrW63/4TkQY0yr50RcLlfIP8A/rg223pw5c/T000+HtO1QtbWHyy67rOnrSy65xPFw\nVWe66qqrdN1112nbtm1KSkrq8PZ+OK4ePXro0ksvbfq6sbEx6DpO+6Klfex0Tq29r7VQXndRUVFB\nayQpISFB5eXl2rRpk5544gmNHz9ev/nNb0Ja10lERESzQ9lOr58ZM2Zo3bp1OnTokPLy8lqti4yM\n1MCBA/Xaa69p9OjRGjp0qLZu3aoDBw60+tr43//+p+PHjysQCOjkyZO64oorWt3+Pffco9WrV+vw\n4cOaO3eu4/hee+01+f3+i/acHjOsTlJbW6vevXurZ8+e2rdvn3bu3OlY/9lnnzXVvPHGG63+5nbj\njTfqb3/7m44cOSJJTf+25IYbbtD69et16tQp1dXVaePGja3+5zR+/HitW7dOX375ZdN2P/vss6Dj\nDGbMmDH65z//qfr6eh07dkybNm2y4gKFSy+9VP/4xz+0Zs2aFv/gPZxkZ2dr/fr1OnnypI4fP671\n69e3+vqRQn+tteX101aff/65evbsqZkzZ+qhhx7S7t27W63t1auX6urqQtpu//799cUXX+jIkSOq\nr6/Xxo0bW6294447tHbtWq1bt04zZsxw3G52draWLVumsWPHKjs7W6+88oqGDRvWan1+fr6eeuop\n3XnnnUHPu916660qLS3Vrl27lJub22rdu+++q+XLl3fpRU5djRlWJ5kwYYJeeeUVpaSkKDExsekQ\nTEtcLpcSExP14osvau7cuRoyZIjmz5/fYm1KSooef/xxjR07VpdccomGDRumP/zhDy3WZmRk6I47\n7pDX69XVV1/teKgmOTlZTz31lH72s5/p9OnTioyM1EsvvaRrr73Wse9gRowYoSlTpmjo0KHq37+/\n0tLSdOWVV4a8zWCP0Z7/QENZx+Vy6YorrtDGjRv105/+VL169dItt9zS7m06jctphhPKY2RkZOjn\nP/950/N77733yuv1ttpLqK+1H79+MjMzg86yQn0+PvjgAz388MNNs02ny9b79u2rMWPGKC0tTZMm\nTXL8bL3IyEg9+eSTGjlypNxut1JSUlrtKSUlRceOHZPH41H//v0d+83OztbTTz+tUaNG6fLLL9fl\nl1/eatCvWbNGl112mfLy8nT69GmNHj1aPp9POTk5rfZ84403qnfv3o7778UXX9TXX3+tcePGSZIy\nMzO1atUqx767G/5wGJ3u+PHjioqK0okTJzR27Fi9+uqrSk9P75Jevvrqqy49N9bVqqqqNHnyZH3w\nwQdtXnfJkiWKjo7WokWLOqGzi9fp06c1fPhwrVu3ToMHD+7qdsIahwTR6e677z5lZGRo+PDhmj59\nepeF1cGDBzV69Gg9/PDDXfL44aIjh/VsOJxrk4qKCiUkJOimm24irELADAsAYAVmWAAAKxBYAAAr\nEFgAACsQWAAAKxBYAAArEFgAACv8P5ZWvQDqsWNNAAAAAElFTkSuQmCC\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xae9fc90c>"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6a"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 10,
+       "text": [
+        "'CPYYL GVVIR PDDVU BCSUP QOWPW SYBYP ODBCS PBBPR CSIOZ PTSTV HYVTW PYOZC OGCRV TTPUI BVGVS YOUGZ ZSRYS BPYLY SHSYY OUGBV BCSWP OUBOU GPUIR DSPYD LTSUB OVUOU GZPYP ZSSTZ DONSB CSLNU SJPAV EBBCS ZRPTV EYHYO SUIDL ZZVHH ORSYJ PZWDP UUOUG BVWED DBCSL WORNS IEWCS YBYPO DBCSU OGCBP HBSYZ CSJSU BTOZZ OUGAE BLVER PUYSP IPAVE BBCPB OUBCS OYYSW VYBZB ODDUV MVLVU GSBBO UGPRR SZZBV BCSVY OGOUP DTOZZ TVUPO UBCSG PDDSY LPUIO PTASG OUUOU GBVBC OUNJS TOGCB USSIB VYVDD VEBPA DPRNA PGMVA LVEJP UBBVI VOBVY ZCPDD OALBC SJPLO JPZZE YWYOZ SIALB COZYS WVYBB CSVBC SYWPW SYZJS CPFSH YVTBC SUPQO ZPBBC OZDSF SDPYS SURYL WBSIE ZOUGA OHOIV YWDPL HPOYZ BLDSR OWCSY ZBCOZ VUSOZ UBTPL ASBCS ROWCS YRDSY NJPZV HHIEB LBCPB IPLJS GVBDE RNL\\n'"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len(sanitise(c6b))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 11,
+       "text": [
+        "1573"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6as = sanitise(c6a)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "frequencies(ngrams(c6as, 2))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 13,
+       "text": [
+        "Counter({'bc': 21, 'cs': 20, 'ou': 15, 'sy': 12, 'oz': 10, 'ug': 10, 'ub': 8, 'bv': 8, 'su': 7, 'bb': 7, 'zz': 6, 'yo': 6, 'dd': 6, 'ys': 6, 'py': 6, 'pu': 6, 'jp': 6, 've': 6, 'vy': 6, 'cp': 5, 'co': 5, 'si': 5, 'yz': 5, 'ds': 5, 'po': 5, 'bo': 5, 'eb': 5, 'vb': 5, 'vu': 5, 'sb': 4, 'zb': 4, 'yb': 4, 'dp': 4, 'pl': 4, 'pd': 4, 'pb': 4, 'pz': 4, 'bp': 4, 'js': 4, 'wp': 4, 'og': 4, 'up': 4, 'uo': 4, 'ui': 4, 'yl': 4, 'tv': 3, 'to': 3, 'lv': 3, 'lb': 3, 'yv': 3, 'sj': 3, 'sg': 3, 'sp': 3, 'sr': 3, 'ss': 3, 'sw': 3, 'zs': 3, 'zv': 3, 'zc': 3, 'al': 3, 'yw': 3, 'rn': 3, 'rp': 3, 'db': 3, 'us': 3, 'yy': 3, 'yp': 3, 'st': 3, 'ie': 3, 'gv': 3, 'gp': 3, 'zp': 3, 'gb': 3, 'gc': 3, 'pa': 3, 'pt': 3, 'pr': 3, 'bl': 3, 'wc': 3, 'ow': 3, 'od': 3, 'vh': 3, 'vt': 3, 'hy': 3, 'tp': 2, 'ts': 2, 'cb': 2, 'lw': 2, 'fs': 2, 'sh': 2, 'sl': 2, 'so': 2, 'sz': 2, 'sv': 2, 'zo': 2, 'ro': 2, 'wv': 2, 'rd': 2, 'ry': 2, 'rs': 2, 'dl': 2, 'do': 2, 'dv': 2, 'ir': 2, 'ip': 2, 'qo': 2, 'io': 2, 'ib': 2, 'gz': 2, 'ga': 2, 'av': 2, 'go': 2, 'pw': 2, 'pq': 2, 'by': 2, 'bs': 2, 'bt': 2, 'wd': 2, 'oy': 2, 'or': 2, 'ws': 2, 'iv': 2, 'zd': 2, 'ey': 2, 'er': 2, 'ns': 2, 'vi': 2, 'nj': 2, 'ho': 2, 'uu': 2, 'hh': 2, 'mv': 2, 'as': 2, 'tz': 1, 'tt': 1, 'tw': 1, 'ta': 1, 'tb': 1, 'lp': 1, 'lt': 1, 'ly': 1, 'lz': 1, 'la': 1, 'ld': 1, 'lg': 1, 'lh': 1, 'lj': 1, 'cr': 1, 'lo': 1, 'ln': 1, 'wb': 1, 'sc': 1, 'sd': 1, 'sf': 1, 'na': 1, 'zr': 1, 'ap': 1, 'wo': 1, 'zw': 1, 'zu': 1, 'zt': 1, 'zy': 1, 'ad': 1, 'ae': 1, 'zj': 1, 'ao': 1, 'rc': 1, 'hb': 1, 'rr': 1, 'rv': 1, 'yj': 1, 'yh': 1, 'yn': 1, 'hi': 1, 'de': 1, 'yd': 1, 'yr': 1, 'du': 1, 'dt': 1, 'nl': 1, 'gm': 1, 'wy': 1, 'ia': 1, 'id': 1, 'gs': 1, 'pi': 1, 'ph': 1, 'pg': 1, 'pf': 1, 'bz': 1, 'bu': 1, 'bi': 1, 'bd': 1, 'we': 1, 'ov': 1, 'op': 1, 'os': 1, 'on': 1, 'oi': 1, 'oj': 1, 'oa': 1, 'ob': 1, 'ej': 1, 'ze': 1, 'ed': 1, 'ez': 1, 'ew': 1, 'vg': 1, 'vd': 1, 'va': 1, 'vo': 1, 'oh': 1, 'nu': 1, 'vl': 1, 'vw': 1, 'vv': 1, 'vs': 1, 'uy': 1, 'uv': 1, 'ur': 1, 'un': 1, 'hp': 1, 'hs': 1, 'vm': 1})"
+       ]
+      }
+     ],
+     "prompt_number": 13
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "' '.join(segment(letters(c6a).translate(''.maketrans({'B':'t', 'C':'h', 'S':'e', 'O':'i', 'U':'n', 'G':'g', 'A':'b', 'V':'o', 'N':'k', 'J':'w', 'T':'m', 'I':'d', 'P':'a', 'W':'p', 'R':'c', 'Y':'r', 'L':'y', 'D':'l', 'H':'f', 'Z':'s', 'Q':'z', 'E':'u', 'F':'v', 'M':'j'}))))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 14,
+       "text": [
+        "'harry good call on the nazi paper trail the attached is a memo from paris high command to goering s secretary referring to the painting and clearly mentioning sara seems like they knew about the scam our friendly ss officer was planning to pull they picked up her trail the night after she went missing but you can read about that in their report still no joy on getting access to the original miss mona in the gallery and i am beginning to think we might need to rollout a black bag job you want to do it or shall i by the way i was surprised by this report the other papers we have from the nazis at this level are encrypted using bifid or playfair style ciphers this one isnt maybe the cipher clerk was off duty that day we got lucky'"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "trans={'B':'t', 'C':'h', 'S':'e', 'O':'i', 'U':'n', 'G':'g', 'A':'b', 'V':'o', 'N':'k', 'J':'w', 'T':'m', 'I':'d', 'P':'a', 'W':'p', 'R':'c', 'Y':'r', 'L':'y', 'D':'l', 'H':'f', 'Z':'s', 'Q':'z', 'E':'u', 'F':'v', 'M':'j'}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join(sorted(trans.keys(), key=lambda k: trans[k]))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 16,
+       "text": [
+        "'PARISHGCOMNDTUVWYZBEFJLQ'"
+       ]
+      }
+     ],
+     "prompt_number": 16
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "' '.join(segment(keyword_decipher(c6as, 'parishighcommand', 2)))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 17,
+       "text": [
+        "'harry good call on the nazi paper trail the attached is a memo from paris high command to goering s secretary referring to the painting and clearly mentioning sara seems like they knew about the scam our friendly ss officer was planning to pull they picked up her trail the night after she went missing but you can read about that in their report still no joy on getting access to the original miss mona in the gallery and i am beginning to think we might need to rollout a black bag job you want to do it or shall i by the way i was surprised by this report the other papers we have from the nazis at this level are encrypted using bifid or playfair style ciphers this one isnt maybe the cipher clerk was off duty that day we got lucky'"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6bs = sanitise(c6b)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len(c6bs)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 19,
+       "text": [
+        "1573"
+       ]
+      }
+     ],
+     "prompt_number": 19
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from itertools import permutations"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 20
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "list(permutations(range(4)))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 21,
+       "text": [
+        "[(0, 1, 2, 3),\n",
+        " (0, 1, 3, 2),\n",
+        " (0, 2, 1, 3),\n",
+        " (0, 2, 3, 1),\n",
+        " (0, 3, 1, 2),\n",
+        " (0, 3, 2, 1),\n",
+        " (1, 0, 2, 3),\n",
+        " (1, 0, 3, 2),\n",
+        " (1, 2, 0, 3),\n",
+        " (1, 2, 3, 0),\n",
+        " (1, 3, 0, 2),\n",
+        " (1, 3, 2, 0),\n",
+        " (2, 0, 1, 3),\n",
+        " (2, 0, 3, 1),\n",
+        " (2, 1, 0, 3),\n",
+        " (2, 1, 3, 0),\n",
+        " (2, 3, 0, 1),\n",
+        " (2, 3, 1, 0),\n",
+        " (3, 0, 1, 2),\n",
+        " (3, 0, 2, 1),\n",
+        " (3, 1, 0, 2),\n",
+        " (3, 1, 2, 0),\n",
+        " (3, 2, 0, 1),\n",
+        " (3, 2, 1, 0)]"
+       ]
+      }
+     ],
+     "prompt_number": 21
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[column_transposition_decipher(c6bs, p, fillvalue=' ') for p in permutations(range(4))]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 22,
+       "text": [
+        "['hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnroteletpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvnaiaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrtebltllgfo   ',\n",
+        " 'hihthnrffetreafoftanslytorrreqhtimesrurlhfestaeeiuwisibhnrtrsiioieinrhrmpydttoierctialbnrphntoohrleiwthstepsostooyunwherdhchpimcnotoahsahtjieaentorfnesuramgxutrtolweabtrtpeptaraeesnehthrsinrtsstnrflodghuamgessekaunitahtytnuyntnnvhgiwlwefipaaserlfiaebpacmpclaehthotlhswuldasevueaoetauetaetefhelbthrsghatilaceehtnrhgaasiteufnnpuerhrleitmtudiynneugiocuedneeaihseulhntoathieianydfniuaoeantieyfoehdaulareoryuhrareatreahaiontgwiwssatibutlaoxmleotretootnoaorotgcbvapinleewfrytaoeadwuwertrtlnrppfailelrmintorwiqereucardnotfanrtoeltepernpmhsndedtdweheofypdeensnnegetaeteaensetrgduleorsbuorwhgdbrapheynttkeretrrrnhfndeolstwsainipyotmhoucotyieeeopnhrknnatirtleeuirenmitpahoaeohnhoumutksvendeeeiodpkwietgiioisehnuuafnbueitrhaehrieheuaaysrsuiwagdssiitlrgfhpilwtiiisheusrmormaecisiolvedoeulsariidoetnifesbontaspogfsordtfriplatnertlyoisoytoessfnptheiageoaraeiitmdtaeagryhasrrcflerteleaenhvheivhmnassieorixmlpstjteosfbrmhnidocehcntbtnocmpsueseohtneetifenootnowoteeritloidgosemhofimlorefdftuseofelrwiiyqbdzottnrafntidgotnaleapdhseanmthplsntbuohaaapllenmpdsrhvanialenhacliksacodaetdjgohiedagwyandteenehgeueeoeednroyyfrctmettnwtgedtausootofwmyihgrrheosirnraforeftenopyasisesstnhhayuelhwipcetataupenalueelwhaaoleursenbiieaasetaegccdsoerpsoreneslvsoeddusilttetitfesoenslnignorentieeiwwlwtheisriihltdrsndserfrhntglrsauseaddotyasdautnewictnaemtetrposeyttoocynutosgcumdlapdlaedoetfdbsfeelahxarsnoiditeirpasihcdschibpiesllnlahofrretnatroaimeklgaremtrdwcsnyanwvsnudlorkeutnnouitiunnhvineiolhletfneaatiuftatceltnnbrhbgelonsaomnifokarnosnnvfrterctfhdtepsswuceprctwpowafhadyiosoaogaenldfgingtrebtlllfgo   ',\n",
+        " 'htihhfnrfreteoaffntastlyorrretqhismerlurhsfeteaeiiuwshibnrrtsoiiineirmhrptydteoirictanlbrnphthoorilewsthtsepoostonyuwrhedhhcpcimnootaahshitjenaetfornuesrgamxruttwoletabretpprtaaseentehhirsnsrtsrtnfdlogahumsgesaekutniayhttynunntnvihgwelwfaiparselafieabpccmplhaettholwhsualdsueveeaoteauttaeeefhlhbtrhsgaltiaecehrtnhagaseitunfnprueherlittmuydinunegciounedeieahuselthnohatiaeinfydnaiuoneatyiefhoedlauaorerhyurearaetraihaogntwsiwsiatblutamoxlteoroetootnaoortbgcviapnelewyfrteaoaudwwterrntlrfppaeillirmnrtoweiqrceuanrdoatfnorteeltpnerpsmhnddetedwhfeoyepdennsneegttaeenaesretglduesorbruowdhgbprahneytetkrretrhrnfendotlswisanyipohtmooucteyiepeonkhrntnailrteieurmeniatpheoaohhnouumtvkseendeoeidwpkigetiiiosnehufuanebuihtrarehieehuyaasursigwadissirtlgpfhitlwisiihseurrmomcaeiosildveoleusiariedotfnieosbnstapfogsdortifrptlanterliyostoyosesftnphaeigaeoriaeidtmtaaeghryarsrceflrlteenaehevhimvhnsasireoilxmpjsttseofmbrhdniohcecbnttcnomupseosehetneftieonotwnooeterlitogidomsehiofmrloeffdteusolferiwiydqbztotnfrandtignotaalepsdhemantlhpsbntuaohalaplmenprdshnvaiealnchalsikadcoadetjhgoiaedgawynedtehnegeeueeoedonryryfcetmtwtntdgetsauoootfywmirhgrohesnirroafrtefepnoyiasssesthnhaeyulihwptceautapaenleuelawhaeoluersnibiesaaeetagdccsroeprsoesnelovseuddstiltiettsfeosenlgnineornetiewiwlhwterisilihtsdrnedsrhfrnltgrusasdeadyotaasduetnwticnmaetretpeosyottoncyustogmcudpladeladtoefsdbfleeaahxrosnitdiepirahsiccdshpibileslanlhrofrnetaotraeimkalgrtemrcdwsanynswvnludoerkuntnotuiinunhnvieliohtlefaneautifttactelnrnbhebglsonanomikfoaornsvnnfertrfcthedtpwssupcerwctpaowfdhaysioogaoalendifgnrgtelbtlglfo   ',\n",
+        " 'hhithrnffterefaofatnsyltorrrehqtiemsrrulhefsteaeiwuisbihntrrsiioiienrrhmpdyttioertciablnrhpntoohreliwhtstpesotsoouynwehrdchhpmicntooashahjtieeantrofnseurmagxturtlowebatrptepatraeesnhethsrintrssntrfoldguhamegsskeauintathytunynntnvghiwwlefpiaaesrlifaepbacpmcleahtohtlshwudlasveueoaetuaeteatehfeltbhrgshaitlaecehntrhagastieunfnpeurhlreimttuidynenugoicudeneaeihesulnhtotahiieandyfnuiaoaenteiyfeohdualaeroruyhrraearteaahiotngwwisstaibtulaxomloetrteoontoarootcgbvpainelewrfytoaeawduwretrltnrppfalielmrinotrwqieruecadrnoftantroetleprenphmsneddtwdehoefydpeesnnngeeteateeanstergudlerosbourwghdbarphyentkterterrnrhfdneosltwasinpiyomthocuotiyeeoepnrhknantitrleueirnemiptahaoeonhhomuutskvedneeieodkpwitegioiishenuaufnubeirthaheriheeuaayssruiawgdssiiltrghfpiwltiiishuesromrmeaciisolevdouelsraiiodetinfebsonatspgofsrodtrfipaltnretloyisyotosesfpnthieagoeareaiimtdteaagyrharsrclferetleeanhhveihvmnsasioerimxlptsjtoesfrbmhindoechctnbtoncmspueesohnteeitfeonotonwoetertilodigoesmhfoimolredfftsueoeflriwiybqdztotnarfnitdgtonaelaphdsenamtphlstnbuhoaapallnempsdrhavnilaenahclkisaocdatedjoghideagywantdeeenhgueeeeoedrnoyfyrcmtetntwtegdtuasotoofmwyighrrehosrinrfaorfeteonpysaissesthnhauyelwhipectaatupnealeuelhwaaloeusrenibieaaseategccdseorposreenslsvoedduslittteitefsoneslingnroeniteewiwltwhesirihiltrdsnsderrfhngtlrasusaeddtoyadsauntewcitneamtterpsoeyttooycnuotsgucmdalpdaledeotfbdsfeelaxharnsoiidteripaishcsdchbipiselllnahforrtenartoamiekglarmetrwdcsynanvwsndulokreuntnoiutinunhivneoilheltfenaaitufattcletnbnrhgbelnosamoniofkanrosnnvftrertcfhtdepsswuecprtcwpwoafahdyoisooaganeldgfintgretbllflgo   ',\n",
+        " 'hthihfrnfrteeofafnatstylorrrethqisemrlruhsefteeaiiwushbinrtrsoiiiniermrhptdyteioritcanblrnhpthoorielwshttspeootsonuywrehdhchpcminotoaashhijteneatfronusergmaxrtutwloetbareptprataseenthehisrnstrsrntfdolgauhmsegsakeutinaythtyunnnntvighwewlfapiareslaifeapbccpmlheattohlwshuadlsuveeeoateuatteaeehflhtbrhgsalitaeechrnthaagsetiunnfpreuhelritmtuyidnuengcoiundeeiaehuesltnhohtaiaienfdynauionaetyeifheodluaaoerrhuyreraaertaiahogtnwswisitabltuamxoltoeroteoontaorotbcgvipaneelwyrfteoaauwdwtrernltrfppaelilimrnrotweqircueandroaftnotreetlpnrepshmndedtewdhfoeyedpensnnegetteaeneasrtegludesrobrouwdghbparhnyetektrrterhnrfednotslwiasnypiohmtoocuteiyepoenkrhntaniltreiuermneiaptheaoohnhoumutvskeedneoiedwkpigteiioisnheufauneubihrtarheieheuyaasusrigawdissirltgphfitwlisiihsuerrommceaioisldevoluesiraieodtfineobsnsatpfgosdrotirfptalntrelioystyoosseftpnhaiegaoerieaidmttaeaghyrarrscelfrleteneahehvimhvnssairoeilmxpjtstsoefmrbhdinoheccbtntconmuspeoeshentefiteoontwonoeetrltiogdiomeshifomrolefdftesuolefriiwydbqzttonfarnditgntoaaelpshdemnatlphsbtnuahoalpalmneprsdhnavielancahlskiadocadtejhogiadegaywnetdehengeueeeeodornyrfycemttwnttdegtsuaootofymwirghroehsnrirofartfeeponyisasssethhnaeuyliwhptecauatpaneleeulahwaelouesrniibesaaeeatgdccsreoprosesenlosveuddstlititetsefosnelginneroneitewwilhtwersiilhitsrdnesdrhrfnlgtruassdaedytoaadsuentwtcinmeatrtepesoyottonycusotgmucdpaldealdteofsbdfleeaaxhronsitidepriahisccsdhpbiilselalnhrfornteaortaemikaglrtmercwdsaynnsvwnlduoekrunntotiuinnuhniveloihtelfaenauitftatctlenrbnhegblsnoanmoikofaonrsvnnfetrrftchetdpwssupecrwtcpawofdahysoiogoaalnedigfnrtgeltblgflo   ',\n",
+        " 'hhtihrfnftreefoafantsytlorrrehtqiesmrrluhesfteeaiwiusbhintrrsioiiinerrmhpdtytieorticabnlrhnptohoreilwhsttpseotosounywerhdchhpmcintooasahhjiteenatrfonsuermgaxtrutlwoebtarpetpartaesenhtehsirntsrsnrtfodlguahmesgskaeuitnatyhtuynnnntvgihwwelfpaiaersliafepabcpcmlehatothlswhudalsvueeoeatueatetaeheflthbrghsailtaeechnrthaagsteiunnfperuhlerimttuiydneungociudneeaieheuslnthothaiiaendfynuaioaneteyifehodulaaeorruhyrreaaretaaihotgnwwsistiabtluaxmolotertoeonotarootcbgvpianeelwryftoeaawudwrterlntrpfpaleilmirnortwqeiruceadnrofatntoretelprnephsmneddtwedhofeydepesnnngeetetaeenastreguldersoboruwgdhbaprhynetketrtrernhrfdenostlwaisnpyiomhtocoutieyeopenrkhnatnitlreuiernmeipathaeoonhhomuutsvkedeneioedkwpitgeioiishneuafunuebirhtahreiheeuayassuriagwdsisilrtghpfiwtliisihuserormmecaiiosledvoulesriaioedtifnebosnastpgfosrdotrifpatlnrteloiysytoossefptnhiaegoaereiaimdtteaagyhrarrsclefrelteenahhevihmvnssaioreimlxptjstosefrmbhidnoehcctbntocnmsupeeoshneteifteoontownoeetrtliodgioemshfiomorledfftseuoelfriiwybdqzttonafrnidtgtnoaealphsdenmatplhstbnuhaoaplalnmepsrdhanvileanachlksiaodcatdejohgidaegyawntedeehngueeeeeodronyfrycmettnwttedgtusaotoofmywigrhreohsrnirfoarfteeopnysiasssethhnaueylwihpetcaautpnaeleeulhawaleouserniibeasaeaetgcdcseroporseesnlsovedudsltittietesfonselignnreonietewwilthwesriihlitrsdnsedrrhfngltraussadedtyoadasunetwctinemattrepseoytotoyncuostgumcdapldaeldetofbsdfeleaxahrnosiitderpiaihscscdhbpiislellanhfrortnearotameikgalrmterwcdsyannvswndluokerunntoituinnuhinveolihetlfeanaiutfattcltenbrnhgeblnsoamnoiokfanorsnvnfterrtfchtedpswsuepcrtwcpwaofadhyosioogaanledgifntrgetlblfglo   ',\n",
+        " 'ihthnhfrefrtaeoftfnalstyrorrqethmiseurlrfhseateeuiiwishbrnrtisoieinihrmryptdoteicritlanbprnhotholrietwshetspsootyonuhwrehdhcipcmonothaasthijaeneotfrenusargmuxrtotwlaetbtreptpraeaseenthrhisrnsttsrnlfdohgaugmseesaknutihaytntyutnnnhviglwewifapsareflaibeapmccpalhehttohlwsluadesuvaeeoateuattefeehblhtsrhgtalicaeethrnghaaisetfunnuprerheltitmduyinnueigcoeundeeiashuehltnaohteiaiynfdinaueonaityeofheadluraoeyrhuarertaerhaianogtiwswasitubltoamxeltoerottoonoaorgtbcaviplneefwyrateodauwewtrtrnlprfpiaelrlimtnroiweqercurandtoafrnotleetepnrmpshdndedtewehfopyednensenegatteaeneesrtdgluoesrubrohwdgrbpaehnyttekerrtrrhnnfedlotsswiainyptohmuoocyteieepohnkrnntarilteeiuermntiapoheahohnuoumktvsneedeeoipdwkeigtiiioesnhuufabneutihrearheiehauyarsuswigasdistirlfgphlitwiisiehsumrroamcesioivldeeoluasirdieontfiseobtnsaopfgosdrftirlptaentrylioostyeossnftpehaiegaoarietidmataerghysarrfceltrleaenevhehvimhansseiroxilmspjtetsobfmrnhdicohencbtntcopmusseoethentefineoontwotoeeirltiogdsomeohiflmrofefdutesfolewriiqydbozttrnfatndiogntlaaedpshaemnhtlpnsbtouahaalpelmndprsvhnaaielhncailskcadoeadtgjhoeiadwgaydnetneheegeuoeeendoryyrftcemttwngtdeatsuoootwfymhirghroeisnrarofertfnepoayisesssnthhyaeuhliwcptetauaepanuleewlahoaelruesbniiaesateeacgdcosrespronesevlosdeudistletitftseeosnnlgionertneiiewwwlhtiersiilhdtsrdnesfrhrtnlgsruaesdaodytsaadtueniwtcanmeetrtopestyotconytusocgmuldpaldeaodtedfsbeflehaaxsronditiieprsahidccsihpbeilsnlalohrfernttaoriaemlkagertmdrcwnsaywnsvunldroektunnuotiuinnvhniielolhtenfaetauitftaectlnnrbbhegolsnoanmfikoraonnsvnrfetcrftdhetspwscupecrwtopawhfdaiysoaogoealnfdiggnrtbeltllgf o  ',\n",
+        " 'ihhtnhrfeftraefotfanlsytrorrqehtmiesurrlfhesateeuiwiisbhrntrisioeiinhrrmypdtotiecrtilabnprhnotohlreitwhsetpssotoyounhwerhdchipmcontohasathjiaeenotrfensuarmguxtrotlwaebttrpetpareaesenhtrhsirntstsnrlfodhguagmeseskanuithatyntuytnnnhvgilwweifpasaerfliabepamcpcalehhtothlswludaesvuaeoeatueatetfeheblthsrghtailcaeethnrghaaistefunnuperrhletimtduiynneuigoceudneeaisheuhlntaotheiiayndfinuaeoaniteyofehadulraeoyruharretarehaainotgiwwsastiubtloaxmelotertotonooarogtcbavpilneefwryatoedawuewrttrlnprpfialerlmitnoriwqeerucradntofarntoleteeprnmphsdneddtweehofpydenesnengeatetaeenestrdguloersuborhwgdrbapehynttkeertrrrnhnfdelostswaiinpytomhuocoytieeeophnrknnatritleeuiernmtipaohaehonhuomuktsvnedeeeiopdkweitgiioieshnuuafbnuetirheahreiheauayrssuwiagsdsitilrfghpliwtiiisehusmroramecsiiovledeoulasridioentifsebotnasopgfosrdftrilpatenrtyloiosyteossnfptehiaegoaareitimdateargyhsarrfcletrelaeenvhhevihmansseiorximlsptjetosbfrmnhidcoehnctbntocpmsuseeothneteifneoontowtoeeirtliodgsoemohfilmorfedfutsefoelwriiqybdozttrnaftnidogtnlaeadphsaenmhtplnstbouhaaaplelnmdpsrvhanailehnacilkscaodeatdgjoheidawgyadnteneehegueoeeendroyyfrtcmettnwgtedatusootowfmyhigrhreoisrnarfoerftneopaysiesssnthhyauehlwicpettaauepnauleewlhaoalerusebniiaeasteaecgcdosersporneesvlsodeduisltettifteseonsnligonretnieiewwwlthiesriihldtrsdnsefrrhtnglsrauesadodtysadatuneiwctanemettropsetytocoyntuoscgumldapldaeodetdfbsefelhaxasrnodiitierpsaihdcscihbpeislnllaohfrertntaroiamelkgaermtdrwcnsyawnvsundlroketunnuoituinnvhinieollhetnfeataiutfatecltnnbrbhgeolnsoamnfiokranonsnvrftecrtfdhtespswcuepcrtwopwahfadiyosaoogeanlfdgigntrbetlllfg o  ',\n",
+        " 'thihfhnrrfetoeafnftatslyrorrteqhsimelrurshfeetaeiiuwhsibrnrtosiinieimrhrtpydetoiirctnalbnrphhtooirleswthstepoostnoyurwhehdhccpimonotaahsihtjneaeftorunesgramrxutwtolteabertprptasaeetnehihrssnrtrstndfloaghusmgeasektuniyahtytnunntnivhgewlwafiprasealfiaebpccmphlaetthowlhsaulduseveeaoetauttaeeefhhlbthrsglatieacerhtnahgaesitnufnrpueehrltitmyudiunnecgionuedieeauhsetlhnhoataieifnydaniunoeaytiehfoeldauoarehryuerareatriahagontswiwisatlbutmaoxtleooretootnoaorbtgcivapenleywfretaouadwtwernrtlfrppeaililrmrntoewiqcreunardaotfonrteeltnperspmhdndeetdwfheoeypdnensenegttaeneaersetlgduseorrbuodwhgpbranheyettkrrethrrnefndtolsiwsayniphotmooucetyipeeoknhrtnnalirtieeumrenaitpehoahohnuoumvtkseendoeeiwdpkgietiiionsehfuuaenbuhitrraeheiehyuaausrsgiwaidssritlpgfhtilwsiiisheurrmocmaeoisidlveloeuisareidoftnioesbsntafpogdsoritfrtplatnerilyotsoysoestfnpaheiageoiraeditmataehgryrasrecfllrteneaeehvhmivhsnasrieolixmjpststeomfbrdhnihocebcntctnoumpsoeseehtnfetioenowtnoeotelritgoidmoseihofrmlofefdetuslofeirwidyqbtzotfnradntingotaalespdhmeanlthpbsntauohlaapmlenrpdsnhvaeialcnhaslikdacodaethjgoaiedagwyendtheneegeueeoeodnrryyfectmwttndtgestauoootyfwmrihgorhensiroraftrefpenoiyassseshtnheayuilhwtpceuataapeneluealwheaoleursinbiseaaeetadgccrsoerpsoseneolvsueddtsilitetstfesoenglnienorentiweiwhlwtreisliihstdrendshrfrlntgursadseaydotaasdeutntwicmnaerteteposoyttnocysutomgcupdlaedlatdoesfdblfeeaahxorsntidipeirhasiccdsphibliesalnlrhofnretoatreaimaklgtremcrdwasnysnwvlnudeorknutntouiniunnhvileiothleafneuatitftatcelrnnbehbgslonnaomkifooarnvsnnefrtfrctehdtwpsspucewrctapowdfhasyiogoaolaenidfgrngtlebtgllf o  ',\n",
+        " 'hhitrhnftferfeaoaftnysltrorrheqteimsrrulehfsetaewiuibsihtnrrisioiienrrhmdpytitoetrcibalnhrpnotoherlihwtsptestosouoynewhrcdhhmpictnoosahajhtieeanrtofsneumragtxurltowbeatprteaptreaeshnetshritnrsnstrofldughaemgskseaiunttahyutnynntngvhiwwlepfiaeasrilfapebapcmcelahothtslhwdulavseuoeaeutaeetathefetlbhgrshiatleacenhtrahgatsienufnepurlhremittiudyennuogicduenaeeiehsunlhttoahiieadnyfuniaaoenetiyefohudalearouryhrraerateaahitongwwistsaitbulxaomolettreonotoraooctgbpvaienlerwfyotaewadurwetlrtnprpflaiemlriontrqwieurecdarnfotatnrotelerpenhpmsenddwtdeohefdypesenngneeetateeantserugdlreosoburgwhdabrpyhenkttetrernrrhdfnesoltawsipniymothcouoityeoeeprnhkannttirlueeinrempitaahoenohhmouustkvdeneieeokdpwtiegoiiihsenauufunberithhaerhieeauayssruaiwgsdsilitrhgfpwiltiiisuhesormremaciisoelvduoelrsaioideitnfbesoantsgpofrsodrtfiapltrnetolyiysotsoespfntiheaogeaeraimitdetaaygrhrasrlcfeertleeanhhvehivmsnasoiermixltpsjotesrfbmihndeochtcnbotncsmpueesonhteietfoenootnweotetrildoigeosmfhoiomlrdeffstueeoflirwibyqdtzotanrfintdtgonealahpdsneampthltsnbhuoapaalnlemspdrahvnliaeanhcklisoacdtaedojghdieaygwatndeeenhugeeeeoerdnofyyrmctenttwetgdutastooomfwygihrerhorsinfraofretoenpsyaisseshtnhuayewlhiepctaatunpeaeluehlwalaoesureinbiaeasaetecgcdesoropsreensslvodedulsittteietfsnoesilngrnoeinteweiwtlwhseirhiilrtdssnderrfhgntlarsuasedtdoydasanutecwitenamtterspoetytoyocnoutsugcmadlpadleedotbfdsefelxahanrsoiidtreipiashscdcbhipsielllnafhortrenratomaiegklamretwrdcysnavnwsdnulkorenutnioutniunihvnoeilehltefnaiatuafttlcetbnnrghbenlosmaonoifknaronsnvtfretrcfthdespsweucptrcwwpoaafhdoyisooagnaelgdfitngrteblfllg o  ',\n",
+        " 'thhifhrnrfteoefanfattsylrorrtehqsiemlrrushefeteaiiwuhsbirntrosiiniiemrrhtpdyetioirtcnablnrhphtooirelswhtstpeootsnouyrwehhdchcpmiontoaashihjtneeaftrounsegrmarxtuwtlotebaerptrpatsaeetnheihsrsntrrsntdfolaguhsmegasketuinyathytunnnntivghewwlafpiraesalifaepbccpmhleattohwlshaudlusveeeoaetuatteaeehfhltbhrgslaiteaecrhntahagestinunfrpeuehlrtimtyuidunencgoinudeieaeuhestlnhhotaaiiefndyanuinoaeyteihfeolduaoaerhruyerraeartiaahgotnswwiistalbtumaxotloeorteoontoarobtcgivpaenelywrfetoauawdtwrenrltfrppealiilmrrnotewqicruenadraoftontreetlnpresphmdnedetwdfhoeeydpnesnengetteaneearstelgudserorboudwghpbarnhyeetktrrtehrnrefdntosliwasynpihomtoocuetiypeoeknrhtnanlitrieuemrneaiptehaohonhuomuvtskeednoeiewdkpgiteiioinshefuauenubhirtraheeiheyuaaussrgiawidssriltpghftiwlsiiishuerromcmeaoiisdlevloueisraeiodftinoebssnatfpgodsroitrftpaltnreiloytsyososetfpnahieagoeireadimtateahgyrrarseclflretneeaehhvmihvsnsarioelimxjptsstoemfrbdhinhoecbctnctonumspoeesehntfeitoeonwtoneoetlrtigodimoesihformolfedfetsuloefiriwdybqtztofnardnitngtoaaelsphdmenaltphbstnauholapamlnerpsdnhaveilacnahslkidaocdatehjogaideagywentdheenegueeeeoodrnryfyecmtwtntdtegstuaootoyfmwrighorehnsriorfatrfepeoniysasssehthneauyilwhtpecuaatapneeleualhwealoeusrinibseaaeeatdgccrseorposseenolsvueddtsliittestefsoneglinenroenitwewihltwresilihistrdensdhrrflngturasdsaeydtoaadseunttwcimneartteepsooyttnoycsuotmgucpdaledaltdeosfbdlfeeaaxhornstiidperihaisccsdphbiliseallnrhfonrteoarteamiakgltrmecrwdasynsnvwlndueokrnunttoiuninunhivleoithelafenuaittfattclernbnehgbslnonamokiofoanrvsnneftrfrtcehtdwpsspuecwrtcapwodfahsyoigooalaneidgfrntgletbglfl o  ',\n",
+        " 'hhtirhfntfrefeoaafntystlrorrhetqeismrrluehsfeteawiiubshitnrrisoiiinerrmhdptyiteotricbanlhrnpothoerilhwstptsetoosuonyewrhcdhhmpcitnoosaahjhiteenartfosnuemrgatxrultwobetapretaprteasehnteshirtnsrnsrtofdlugahemsgksaeiutntayhutynnnntgvihwwelpfaiearsilafpeabpccmelhaotthslwhdualvsueoeeauteaettaheeftlhbgrhsialteaecnhrtahagtseinunfeprulhermittiuydenunogciduneaeieehusnlthtohaiiaednfyunaiaoneetyiefhoudlaeaorurhyrrearaetaaihtognwwsitsiatbluxamooltetroenootraooctbgpviaenelrwyfoteawaudrwtelrntprfplaeimlironrtqweiurcedanrfoattnorteelrpnehpsmenddwtedohfedyepsenngneeettaeenatsreugldresoobrugwdhabpryhnektettrrenrhrdfensotlawispnyimohtcoouiteyoepernkhantntilrueienrmepiataheonohhmouustvkdeenieoekdwptigeoiiihsneaufuunebrihtharehieeauyassuraigwsdislirthgpfwitliisiuhseorrmemcaiioseldvuolersiaoieditfnbeosanstgpforsdortifaptlrnteoliyystososepftnihaeogaeeriamidtetaayghrrarslceferlteenahhevhimvsnsaoiremilxtpjsotserfmbihdneohctcbnotcnsmupeeosnhetieftoeonotwneoettrlidogieomsfhioomrldeffsteueolfiriwbydqtztoanfrindttgnoeaalhpsdnemaptlhtsbnhuaopalanlmesprdahnvlieaanchklsioadctadeojhgdiaeygawtnedeehnugeeeeeordonfyrymcetntwtetdgutsatooomfywgirherohrsnifroafrteoepnsyiasssehthnuaeywliheptcaautnpaeeleuhlawlaeosuerinibaesaaeetcgdcesrooprseesnslovdeudlstittieetsfnoseilgnrneoinetwewitlhwserihilirtsdsnedrrhfgnltarusasdetdyodaasnuetcwtienmattrespeotyotyoncoustugmcadpladeledtobfsdeflexaahnrosiitdrepiiahssccdbhpisilellanfhrotrneraotmaeigkalmrtewrcdysanvnswdnlukoernuntiotuninuihnvoeliehtlefaniautafttlctebnrnghebnlsomanooikfnaornsvntfertrfcthedspwseupctrwcwpaoafdhoysiooganalegdiftnrgtelbflgl o  ',\n",
+        " 'ithhnfhrerftaoeftnfaltsyrrorqtehmsieulrrfsheaeteuiiwihsbrrntiosieniihmrrytpdoeticirtlnabpnrhohtoliretswhestpsootynouhrwehhdcicpmoonthaastihjaneeoftreunsagrmurxtowtlatebterptrpaesaeetnhrihsrsnttrsnldfohagugsmeeaskntuihyatnytutnnnhivglewwiafpsraefalibaepmccpahlehttohwlslaudeusvaeeoaetuattefeehbhltshrgtlaiceaetrhngahaiestfnunurperehlttimdyuinuneicgoenudeieasuhehtlnahoteaiiyfndianuenoaiyteohfealduroaeyhruaerrtearhiaangotiswwaistulbtomaxetloeorttoonooargbtcaivplenefywraetoduawetwrtnrlpfrpiealrilmtrnoiewqecrurnadtaofrontleetenprmsphddnedetwefhopeydnneseengatteaneeerstdlguoserurbohdwgrpbaenhytetkerrtrhrnnefdltossiwaiynpthomuoocyetiepeohknrntnarliteieuemrntaipoehahhonuuomkvtsneedeoeipwdkegitiiioenshufuabenuthireraheeihayuarusswgiasidstrilfpghltiwisiieshumrroacmesoiivdleelouaisrdeionftisoebtsnaofpgodsrfitrltpaetnryilootsyesosntfpeahieagoairetdimaaterhgysrarfecltlreaneevehhvmihasnserioxlimsjptestobmfrndhichoenbctnctopumssoeetehntfeinoeonwtoteoeilrtigodsmoeoihflrmoffeduetsfloewiriqdybotztrfnatdniongtlaaedsphamenhltpnbstoauhalapemlndrpsvnhaaeilhcnaislkcdaoedatghjoeaidwagydentnheeeeguoeeenodryryftecmtwtngdteastuoootwyfmhrighoreinsraorfetrfnpeoaiysesssnhthyeauhilwctpetuaaeapnuelewalhoealreusbiniaseateeacdgcorsesrponseevolsdueditsleittfsteesonnglioenrteniiwewwhltiresilihdstrdensfhrrtlngsuraedsaoydtsaadteunitwcamneerttoepstoytcnoytsuocmgulpdaledaotdedsfbelfehaaxsorndtiiipershaidccsiphbelisnallorhfenrttoarieamlakgetrmdcrwnasywsnvulndreoktnunutoiuninvnhiileolthenafetuaittfaetclnrnbbehgoslnonamfkioroannvsnreftcfrtdehtswpscpuecwrtoapwhdfaisyoagooelanfidggrntbletlglf  o ',\n",
+        " 'ihhtnrhfetfrafeotafnlystrrorqhetmeisurrlfehsaeteuwiiibshrtnriisoeiinhrrmydptoitectrilbanphrnoothlerithwseptsstooyuonhewrhcdhimpcotnohsaatjhiaeenortfesnuamrgutxroltwabettpretapreeasehntrshirtnstnsrlofdhugagemseksaniuthtaynutytnnnhgvilwweipfasearfilabpeampccaelhhotthslwlduaevsuaoeeauteaettfheebtlhsgrhtialceaetnhrgahaitsefnunueprrlhetmitdiuynenuiogceduneaeisehuhnltatoheiiaydnfiunaeaonietyoefhaudlreaoyurharretraehaaintogiwwsatsiutbloxameoltetrotnoooraogctbapvilenefrwyaotedwauerwttlrnpprfilaermlitonriqweeurcrdantfoartnolteeerpnmhpsdenddwteeohfpdyensenegneaettaeenetsrdugloresuobrhgwdrabpeyhntkteetrrrnrhndfelsotsawiipnytmohucooyiteeoephrnknantrtileueienrmtpiaoahehnohumoukstvndeeeieopkdwetigioiiehsnuaufbunetriheharehieaauyrssuwaigssditlirfhgplwitiiiseuhsmorraemcsiioveldeuolarsidoienitfsbeotansogpforsdfrtilapterntyolioystesosnpfteihaeogaaeritmidaetaryghsrarflceterlaeenvhhevhimasnseoirxmilstpjeotsbrfmnihdceohntcbnotcpsmuseeotnhetiefnoeonotwteoeitrlidogseomofhilomrfdefustefeolwiriqbydotztranftindotgnleaadhpsanemhptlntsbohuaapalenlmdsprvahnaliehanciklscoadetadgojhediawygadtneneeheugeoeeenrdoyfyrtmcetntwgetdautsotoowmfyhgirheroirsnafroefrtnoepasyiesssnhthyuaehwlicepttaauenpauelewhlaolaersuebiniaaestaeeccgdoesrsoprneesvsloddeuilstettifetsenosnilgornetineiwewwtlhiserihildrtsdsnefrrhtgnlsarueasdotdysdaatnueicwtaenmettrospettyocyontouscugmladpladeoedtdbfseeflhxaasnrodiitirepsiahdsccibhpesilnllaofhretrntraoimaelgkaemrtdwrcnysawvnsudnlrkoetnunuiotuninvihnioellehtnefatiautaftelctnbnrbgheonlsomanfoikrnaonnsvrtfectrfdthesspwceupctrwowpahafdioysaoogenalfgdigtnrbtellflg  o ',\n",
+        " 'tihhfnhrreftoaefntfatlsyrrortqehsmielurrsfheeateiuiwhisbrrntoisineiimhrrtypdeotiicrtnlabnprhhotoilrestwhsetposotnyourhwehhdccipmoontahasithjnaeefotruensgarmruxtwotltaebetrprtpaseaetenhirhssrntrtsndlfoahgusgmeaesktnuiyhatyntuntnnihvgelwwaifprsaeafliabepcmcphalethtowhlsaluduesveaeoeatutateefehhblthsrgltaiecaerthnaghaeistnfunrupeerhlttimyduiunnecigoneudieeaushethlnhaotaeiifyndainuneoayitehofeladuoraehyruearretarihaagnotsiwwiastlubtmoaxtelooertotonooarbgtciavpelneyfwreatoudawtewrntrlfprpeialirlmrtnoeiwqcerunradatofornteletneprsmphddneedtwfehoepydnneseengtatenaeerestldgusoerrubodhwgprbanehyettkrerthrrnenfdtlosiswayinphtomouoceytipeeokhnrtnnalritieeumernatipeohahhonuuomvktsenedoeeiwpdkgeitiiioneshfuuaebnuhtirreaheeihyauaurssgwiaisdsrtilpfghtliwsiiisehurmrocameosiidvleleouiasrediofntiosebstnafopgdosriftrtlpatenriylotosyseostnfpaehiaegoiaredtimaatehrgyrsarefclltrenaeeevhhmvihsansreiolximjsptsetombfrdnhihcoebnctcntoupmsoseeethnfteioneowntoetoelirtgiodmsoeiohfrlmoffedeutslfoeiwridqybtoztfrnadtninogtalaesdphmaenlhtpbnstaouhlaapmelnrdpsnvhaeailchnasilkdcaodeathgjoaeidawgyednthneeeegueoeeondrryyfetcmwttndgtesatuoootywfmrhigohrenisroarfterfpneoiayssesshntheyauihlwtcpeutaaaepneuleawlheoalerusibnisaeaeteadcgcrosersposneeovlsudedtisliettsfteseongnlieonretniwiewhwltriesliihsdtrednshfrrltngusradesayodtasadetuntiwcmaneretteopsotytncoystuomcgupldaeldatodesdfblefeahaxosrntdiipierhsaicdcspihbleisanllrohfnertotareiamalkgtermcdrwansyswnvlunderokntuntuoinuinnvhilieotlheanfeutaittfateclrnnbebhgsolnnoamkfiooranvnsnerftfcrtedhtwspspcuewcrtaopwdhfasiyogaooleanifdgrgntlbetgllf  o ',\n",
+        " 'hihtrnhftefrfaeoatfnylstrrorhqetemisrurlefhseatewuiibishtrnriisoieinrhrmdyptiotetcriblanhprnoothelrihtwspetstsoouyonehwrchdhmipctonoshaajthieaenrotfsenumargtuxrlotwbaetptreatpreeashentsrhitrnsntsrolfduhgaegmskesainutthayuntyntnnghviwlwepifaesariflapbeapmccealhohttshlwdluavesuoaeeuateeatthfeetblhgsrhitalecaenthraghatisenfuneuprlrhemtitiduyennuoigcdeunaeeieshunhlttaohieiadynfuinaaeoneityeofhuadleraouyrhrarertaeahaitnogwiwstasitublxoamoeltterontooroaocgtbpavielnerfwyoatewdaurewtltrnpprfliaemrliotnrqiweuercdranftoatrnotleerepnhmpsedndwdteoehfdpyesnengeneeatteaentesrudglroesoubrghwdarbpyehnktteterrnrrhdnfeslotaswipinymtohcuooiyteoeeprhnkannttrilueeinermptiaaohenhohmuousktvdneeieeokpdwteigoiiihesnauufubnertihhearheieaauysrsuawigssdiltirhfgpwlitiiisuehsomrreamcisioevldueolrasiodieintfbseoatnsgopfrosdrftialptrentoyliyostseospnftiehaoegaearimtideatayrghrsarlfceetrleaenhvhehvimsansoeirmxiltspjoetsrbfminhdecohtncbontcspmueseontheitefoneoontwetoetirldiogesomfohiolmrdfefsuteefoliwribqydtoztarnfitndtognelaahdpsnaemphtltnsbhouapaalnelmsdpravhnlaieahnckilsocadteadogjhdeiaywgatdneenehuegeeoeerndofyyrmtcenttwegtduatstooomwfyghirehrorisnfarofertonepsayisesshnthuyaewhliecptataunepaeulehwlaloaesrueibniaaesateeccgdeosrosprenessvloddeulisttetieftsneosinlgroneitnewiewtwlhsierhiilrdtssdnerfrhgtnlasruaesdtodydsaantueciwteanmtetrsopettyoyconotusucgmaldpaldeeodtbdfseeflxhaansroiditriepisahsdccbihpseillnlafohrternrtaomiaeglkamertwdrcynsavwnsdunlkroentuniuotnuinivhnoielelhtenfaitauatftlectbnnrgbhenolsmoanofiknraonnsvtrfetcrftdhesspwecuptcrwwopaahfdoiysoaognealgfditgnrtbelfllg  o ',\n",
+        " 'thhifrhnrtfeofeanafttyslrrortheqseimlrrusehfeetaiwiuhbsirtnroisiniiemrrhtdpyeitoitrcnbalnhrphotoierlshwtspteotosnuoyrewhhcdhcmpiotnoasahijhtneeafrtousnegmrartxuwltotbeaeprtraptseaethneishrstnrrnstdoflaughsemgaksetiunytahyutnnnntigvhewwlapfireasailfapebcpcmhelatothwslhaduluvseeoeaeutatetaehefhtlbhgrsliateeacrnhtaahgetsinnufrepuelhrtmityiuduenncogindueiaeeuehstnlhhtoaaiiefdnyauninaoeyetihefoludaoearhuryerraeratiaahgtonswwiitsaltbumxaotoleotreonotoraobctgipvaeenlyrwfeotauwadtrwenlrtfprpelaiimlrronteqwicurendarafototnretelnrpeshpmdendewtdfoheedypnsenegnetetaneeartselugdsreorobudgwhpabrnyheekttrtrehnrredfntsoliawsypnihmotocoueitypoeekrnhtannltiriueemnreapiteahohnohumouvstkedenoieewkdpgtieioiinhsefauueunbhritrhaeehieyauaussrgaiwisdsrlitphgftwilsiiisuherormcemaoiisdelvluoeirsaeoidfitnobessantfgpodrsoirtftapltrneiolytysossoetpfnaiheaogeieradmitaetahygrrraselcflertneeaehhvmhivssnaroielmixjtpssotemrfbdihnheocbtcncotnusmpoeesenhtfietooenwotneeotltrigdoimeosifhoromlfdefestuleofiirwdbyqttzofanrdintntgoaealshpdmnealpthbtsnahuolpaamnlerspdnahveliacanhsklidoacdtaehojgadieaygwetndheeneugeeeeoordnrfyyemctwnttdetgsutaotooymfwrgihoerhnrsiofratfrepoenisyasssehhtneuayiwlhtepcuaatanpeeeluahlwelaoesuriinbsaeaeaetdcgcresoropsseenoslvudedtlsiittesetfsnoegilnernoeintwweihtlwrseilhiisrtdesndhrrflgntuarsdaseytdoadasenuttcwimenartteespootytnyocsoutmugcpadleadltedosbfdlefeaxahonrstiidpreihiascscdpbhilsieallnrfhontreoratemaiagkltmrecwrdaysnsvnwldnuekornnuttiounniunihvloeitehlaefnuiattafttlcerbnneghbsnlonmaokoifonarvnsnetfrftrcethdwspspeucwtrcawpodafhsoyigooalnaeigdfrtngltebgfll  o ',\n",
+        " 'hthirfhntrfefoeaanftytslrrorhteqesimrlrueshfeetawiiubhsitrnriosiiniermrhdtpyietotircbnalhnrpohtoeirlhswtpstetoosunoyerwhchdhmcpitonosaahjihtenearftosunemgratrxulwtobteapertarptesaehtnesihrtsnrnrstodfluaghesmgkaseituntyahuytnnnntgivhwewlpafierasialfpaebpccmehlaotthswlhdaulvuseoeeauetaettaheefthlbghrsilateeacnrhtaahgtesinnuferpulehrmtitiyudeunnocgidnueaieeeuhsntlhthoaiaiedfnyuanianoeeytiehfouldaeoaruhryrerareataiahtgonwswitisatlbuxmaootletorenootroaocbtgpivaeenlrywfoetawuadrtwelnrtpfrpleaimilrorntqewiucrednarfaottonrteelrnpehspmedndwetdofhedeypsnengeneettaeneatrseulgdrseoorbugdwhapbrynheketttrrenhrrdefnstolaiwspynimhotcoouietyopeerknhatnntliruieenmrepaitaehonhohmuousvtkdeenioeekwdptgieoiiihnseafuuuenbrhithraeheieayuasusragiwsidslrithpgfwtilisiiusheorrmecmaioisedlvuloerisaoeidiftnboesasntgfpordsoritfatplrtneoilyytsossoeptfniaheoageeiramditeatayhgrrraslecfelrteneahehvhmivssnaoriemlixtjpsostermfbidhnehoctbcnoctnsumpeoesnehtifetooenowtneeottlridgoiemosfihoormldfefsetuelofiirwbdyqttzoafnridnttngoeaalhspdnmeaplthtbsnhauoplaanmlesrpdanhvleiaacnhksliodactdaeohjgdaieyagwtendehenuegeeeeorodnfryymectnwttedtgustatooomyfwgriheorhrnsiforaftreopensiyasssehhtnueaywilhetpcauatnapeeeluhalwleaoseuriinbaseaaeetcdgcersoorpsesensolvduedltsititeestfnsoeiglnrenoientwweithlwsreihliirstdsendrhrfglntaursadsetydodaasneutctwiemnatrtesepotoytynocosutumgcapdlaedletdobsfdelfexaahnorsitidrpeiihassccdbphislielalnfrhotnreroatmeaigaklmtrewcrdyasnvsnwdlnukeornnutitounniuinhvoleiethleafniuatatftltcebrnngehbnslomnaookifnoarnvsntefrtfrctehdswpsepuctwrcwapoadfhosyiogoanlaegidftrngtlebfgll  o ',\n",
+        " 'ithhnfrhertfaofetnafltysrrroqthemseiulrrfsehaeetuiwiihbsrrtnioiseniihmrrytdpoeitcitrlnbapnhrohotliertshwesptsotoynuohrewhhcdicmpootnhasatijhaneeofrteusnagmrurtxowltatbeteprtrapeseaethnrishrstntrnsldofhauggsemeaksntiuhytanyuttnnnhigvlewwiapfsreafailbapemcpcahelhtothwslladueuvsaeoeaeutatetfehebhtlshgrtliaceeatrnhgaahietsfnnuureprelhttmidyiunuenicogendueiaesuehhtnlahtoeaiiyfdniaunenaoiyetohefaludroeayhuraerrterahiaangtoiswwaitsultbomxaetoleotrtonoooragbctaipvleenfyrwaeotduwaetrwtnlrpfprielarimltronieqwecurrndataforotnleteenrpmshpddendewtefohpedynnseeegnatetaneeertsdlugosreurobhdgwrpabenyhtektertrrhnrnedfltsosiawiypnthmouocoyeitepoehkrnntanrltieiueemnrtapioeahhhnouumokvstnedeeoiepwkdegtiiioienhsufaubeunthrierhaeehiayaurusswgaisisdtrlifphgltwiisiiesuhmroracemsoiivdeleluoairsdeoinfitsobetsanofgpodrsfirtltapetrnyiolotysessontpfeaiheaogaiertdmiaaetrhygsrrafelctleraneevehhvmhiassneroixlmisjtpesotbmrfndihcheonbtcncotpusmsoeetenhtfienooenwotteeoiltrigdosmeooifhlromffdeuestfleowiirqdbyottzrfantdinontglaeadshpamnehlptnbtsoahualpaemnldrspvnahaelihcanisklcdoaedtaghojeadiwaygdetnnheeeeugoeeenordyrfytemctwntgdetasutootowymfhrgihoerinrsaofretfrnpoeaisyesssnhhtyeuahiwlcteptuaaeanpueelwahloelaresubiinasaeteaecdcgoressropnseevosldudeitlseittfsetesnongiloernteiniwwewhtlirseilhidsrtdesnfhrrtlgnsuaredasoytdsadatenuitcwamenerttoesptotycnyotsoucmuglpadleadoteddsbfelefhaxasonrdtiiipreshiadcscipbhelsinallorfhentrtoraiemalagketmrdcwrnayswsvnuldnrekotnnuutiounnivnihiloeltehnaeftuiattafetlcnrbnbeghosnlonmafkoironanvnsretfcftrdethswspcpeucwtroawphdafisoyagooelnafigdgrtnbltelgfl   o',\n",
+        " 'ihthnrfhetrfafoetanflytsrrroqhtemesiurlrfeshaeetuwiiibhsrtrniioseinihrmrydtpoietctirlbnaphnroohtleirthswepststooyunoherwhchdimcpotonhsaatjihaeneorftesunamgrutrxolwtabtetpertarpeesaehtnrsihrtsntnrslodfhuaggesmekasnituhtyanuyttnnnhgivlwewipafserafialbpaempccaehlhotthswlldauevusaoeeauetaettfheebthlsghrtilaceeatnrhgaahitesfnnuuerprlehtmtidiyuneuniocgednueaieseuhhntlathoeiaiydfniuaneanoieytoehfauldreoayuhrarertreahaiantgoiwswatisutlboxmaeotletortnoooroagcbtapivleenfrywaoetdwuaertwtlnrppfrilearmiltorniqeweucrrdnatfaortonlteeernpmhspdedndweteofhpdeynsneegenaettaeneetrsdulgorseuorbhgdwrapbeynhtketetrrrnhrndeflstosaiwipyntmhoucooyieteopehrknnatnrtlieuieenmrtpaioaehhnhoumuoksvtndeeeioepkwdetgiioiiehnsuafubuentrhiehraeheiaayursuswagissidtlrifhpglwtiiisieushmorraecmsioivedleuloarisdoeiniftsboetasnogfpordsfritlatpertnyoiloytsessonptfeiaheoagaeirtmdiaeatryhgsrraflectelraenevhehvhmiassneorixmlistjpeostbrmfnidhcehontbcnoctpsumseoetnehtifenooenowtteeoitlridgosemoofihlormfdfeusetfelowiirqbdyottzrafntidnotngleaadhspanmehpltntbsohauaplaenmldsrpvanhaleihacnikslcodaetdagohjedaiwyagdtenneheeuegoeeenrodyfrytmectnwtgedtaustotoowmyfhgriheorirnsaforeftrnopeasiyesssnhhtyueahwilcetptauaenapueelwhalolearseubiinaasetaeeccdgoerssorpnesevsolddueiltsetitfestensoniglorentieniwwewthlisreihlidrstdsenfrhrtglnsaureadsotydsdaatneuictwaemnetrtosepttoycynotosucumglapdlaedoetddbsfeelfhxaasnorditiirpesihadsccibpheslinlalofrhetnrtroaimealgakemtrdwcrnyaswvsnudlnrkeotnnuuitounnivinhiolelethneaftiuatatfeltcnbrnbgehonslomnafokirnoannvsrtefctfrdtehsswpcepuctwrowaphadfiosyaogoenlafgidgtrnbtlelfgl   o',\n",
+        " 'tihhfnrhretfoafentaftlysrrrotqhesmeilurrsfeheaetiuwihibsrrtnoiisneiimhrrtydpeoitictrnlbanphrhootilersthwseptostonyuorhewhhcdcimpootnahsaitjhnaeefortuesngamrrutxwolttabeetprrtapseeatehnirshsrtnrtnsdlofahugsgemaekstniuyhtaynutntnnihgvelwwaipfrseaafilabpecmpchaelthotwhslalduuevseaoeeauttaetefhehbtlhsgrltiaeceartnhagaheitsnfnurueperlhttmiydiuunenciogneduieaeusehthnlhatoaeiifydnaiunneaoyiethoeflaudoreahyurearretraihaagntosiwwiatslutbmoxateoloetrotnooorabgctiapvelenyfrweaotudwaterwntlrfppreilairmlrtoneiqwceurnrdaatfoortneltenerpsmhpddenedwtfeohepdynnseeegntaetnaeeretsldugsoreruobdhgwprabneyhetktretrhrnrendftlsoisawyipnhtmooucoeyitpeoekhrntnanlrtiieuemenratpieoahhhnouumovkstendeoeiewpkdgetiiioinehsfuauebunhtrirehaeehiyaauurssgwaiissdrtlipfhgtlwisiiiseuhrmorcaemosiidvelleuoiarsedoifnitosbestanfogpdorsifrttlapterniyoltoyssesotnpfaeihaeogiaerdtmiaaethrygrsraeflclternaeeevhhmvhisasnreoilxmijstpseotmbrfdnihhceobntccnotupsmoseeetnhftieonoewnoteteolitrgidomseoiofhrlomffdeeustlfeoiwirdqbytotzfrandtinnotgaleasdhpmanelhptbntsaohulapamenlrdspnvahealichansikldcoadetahgojaediawygedtnhneeeeugeoeeonrdryfyetmcwtntdgetsautootoywmfrhgiohernirsoafrtefrpnoeiasysesshnhteyuaihwltceputaaaenpeuelawhleolaersuibinsaaeetaedccgroesrsopsneeovsluddetilsiettsfetsenognileornetinwiwehwtlriselihisdrtedsnhfrrltgnusardeasyotdasdaetnuticwmaenretteospottyncyostoumcugpladeladtoedsdbfleefahxaosnrtdiipirehsiacdscpibhlesianllrofhnetrotraeimaalgktemrcdwranysswvnludnerkontnutuionuninvihlioetlehanefutiattaftelcrnbnebghsonlnomakfoiornavnnsertffctredthwssppceuwctraowpdhafsioygaoolenaifgdrgtnlbteglfl   o',\n",
+        " 'hithrnfhterffaoeatnfyltsrrrohqteemsirulrefsheaetwuiibihstrrniiosienirhmrdytpioettcirblnahpnroohtelirhtswpesttsoouynoehrwchhdmicptoonshaajtiheaneroftseunmagrturxlowtbatepteratrpeesahetnsrihtrsnntrsoldfuhagegsmkeasintuthyaunytntnnghivwlewpiafesraifalpbaepmcceahlohttshwldlauveusoaeeuaeteatthfeetbhlgshritlaeceantrhagahtiesnfnueurplrehmttiidyuenunoicgdenuaeieesuhnhtltahoieaidyfnuianaenoeiyteohfualderoauyhrraerrteaahiatngowiswtaistulbxomaoetlteorntoorooacgbtpaivelenrfywoaetwduaretwltnrppfrlieamrilotrnqiewuecrdrnaftaotrontleerenphmspeddnwdetoefhdpeysnnegeeneatteanetersudlgroseourbghdwarpbyenhktetterrnrhrdnefsltoasiwpiynmthocuooiyetoeperhknantntrliueienemrptaiaoehnhhomuuoskvtdneeieoekpwdtegioiiihensaufuubenrthiheraheeiaayusrusawgissidltrihfpgwltiiisiueshomrreacmisoievdlueloraisodeiinftbsoeatsngofprodsrfitaltpretnoyilyotssesopntfieahoeageairmtdieaatyrhgrsralfecetlreanehvehhvmisasnoerimxlitsjpoestrbmfindhechotnbconctspumesoentehitfeonoeonwteteotilrdigoesmofoiholrmdffesuetefloiwirbqdytotzarfnitdntongelaahdspnamephlttnbshoaupalanemlsdrpavnhlaeiahcnkislocdatedaoghjdeaiywagtdenenheueegeoeernodfyrymtecntwtegdtuasttooomwyfghriehorrinsfaorfetronpesaiysesshnhtuyeawhilectpatuaneapeuelhwalloeasreuibinaaseateeccdgeorsosrpensesvoldduelitsteitefstnesoinglroenitenwiwetwhlsirehilirdstsdenrfhrgtlnasuraedstoyddsaanteucitweamntertsoepttoyycnootsuucmgalpdaledeotdbdsfeelfxhaansoridtiripeishasdccbiphselilnalforhtenrrtoamieaglakmetrwdcrynasvwsndulnkreontnuiutonuniivnhoileelthenafituaattfletcbnrngbehnoslmonaofkinroannvstreftcfrtdehsswpecputcwrwoapahdfoisyoagonelagfidtgrntbleflgl   o',\n",
+        " 'thihfrnhrtefofaenatftylsrrrothqesemilrursefheeatiwuihbisrtrnoiisnieimrhrtdypeiotitcrnblanhprhootielrshtwspetotsonuyorehwhchdcmipotonashaijthneaefrotusengmarrtuxwlottbaeeptrratpseeathenisrhstrnrntsdolfauhgsegmakestinuythayuntnntnighvewlwapifresaaiflapbecpmchealtohtwshladluuveseoaeeuatteatehfehtblhgsrlitaeecarnthaaghetisnnfureupelrhtmtiyiduuenncoigndeuiaeeueshtnhlhtaoaieifdynauinnaeoyeitheofluadoerahuyrerarertaiahagtnoswiwitasltubmxoatoeloterontooroabcgtipaveelnyrfweoatuwdatrewnltrfppreliaimrlrotneqiwcuerndraaftootrnetlenrepshmpdednewdtfoehedpynsneegenteatneaertesludgsroeroubdghwparbnyehekttrterhnrrednftsloiaswypinhmtoocuoeiytpoeekrhntannltriiueemneraptieaohhnhoumuovsktedneoieewkpdgteiioiinhesfauueubnhrtirheaeheiyaauusrsgawiissdrltiphfgtwlisiiisuehromrceamoisidevllueoiraseodifintobsesatnfgopdrosirfttalptrenioyltyossseotpnfaiehaoegieardmtiaeathyrgrrsaelfcletrneaeehvhmhvissanroeilmxijtspsoetmrbfdinhhecobtnccontuspmoeseenthfiteoonewonteetoltirgdiomesoifohrolmfdfeesutlefoiiwrdbqyttozfarnditnntogaelashdpmnaelphtbtnsahoulpaamnelrsdpnavhelaicahnskildocadteahogjadeiaywgetdnheneeuegeeoeorndrfyyemtcwnttdegtsuatotooymwfrghioehrnrisofartferponeisaysseshhnteuyaiwhltecpuataanepeeulahwleloaesruiibnsaaeeatedccgreosrospseneosvluddetlisitetseftsneoginleroneitnwwiehtwlrsielhiisrdtesdnhrfrlgtnuasrdaesytodadsaentutciwmeanrtetesopottynycosotumucgpaldealdteodsbdfleefaxhaonsrtidipriehisacsdcpbihlseialnlrfohnterortaemiaaglktmercwdraynssvwnldunekronntutiuonnuinivhloietelhaenfuitatatftlecrbnnegbhsnolnmoakofionravnnsetrfftcretdhwssppecuwtcrawopdahfsoiygoaolneaigfdrtgnltbegfll   o',\n",
+        " 'htihrfnhtreffoaeantfytlsrrrohtqeesmirluresfheeatwiuibhistrrnioisineirmhrdtypieotticrbnlahnprohoteilrhstwpsettosounyoerhwchhdmciptoonsahajithenaerfotsuenmgartruxlwotbtaepetrartpeseahtensirhtsrnnrtsodlfuahgesgmkaesitnutyhauyntnntngihvwelwpaifersaiaflpabepcmcehalothtswhldaluvuesoeaeueatetathefethblghsriltaeecanrthaaghteisnnfueruplerhmttiiydueunnocigdneuaieeeushnthlthaoiaeidfynuainaneoeyitehofuladeorauhyrrearretaaihatgnowsiwtiastlubxmoaoteltoernotorooacbgtpiaveelnryfwoeatwudartewlntrpfprleiamirlortnqeiwucerdnrafatotorntelernephsmpeddnwedtofehdepysnnegeenetatenaetresuldgrsoeorubgdhwaprbynehketttrernhrrdenfstloaiswpyinmhtocouoieytopeerkhnatnntlriuieenmerpatiaeohnhhomuuosvktdeneioeekwpdtgeioiiihnesafuuuebnrhtihreaheeiayausursagwisisdlrtihpfgwtliisiiusehormrecamiosiedvluleoriasoediifntboseastngfoprdosriftatlprtenoiylytossseoptnfiaehoaegeiarmdtieaatyhrgrrsalefceltrenaehevhhmvissanoreimlxitjsposetrmbfidnhehcotbncocntsupmeosenethifteooneownteetotlirdgioemsofiohorlmdffeseutelfoiiwrbdqyttozafrnidtntnogealahsdpnmaeplhttbnshaouplaanmelsrdpanvhleaiachnksilodcatdeaohgjdaeiyawgtednehneueegeeoerondfryymetcnwttedgtusattooomywfgrhieohrrnisfoarfteropnesiaysseshhntueyawihletcpautanaepeeulhawlleoaseruiibnasaeaetecdcgerosorspesnesovldudeltistietesftnseoignlreonietnwwiethwlsriehliirsdtsednrhfrgltnausradestyoddasanetuctiwemantretseoptotyyncoostuumcgapldaeldetodbsdfelefxahanosritdirpieihsascdcbpihsleilanlfrohtnerrotameiagalkmterwcdryansvswndlunkeronntuituonnuiinvholieetlheanfiutaattfltecbrnngebhnsolmnoaokfinoranvnsterftfcrtedhswspepcutwcrwaopadhfosiyogaonleagifdtrgntlbefgll   o']"
+       ]
+      }
+     ],
+     "prompt_number": 22
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6bs"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 23,
+       "text": [
+        "'hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnroteletpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvnaiaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrtebltllgfo'"
+       ]
+      }
+     ],
+     "prompt_number": 23
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join([c[0] for c in every_nth(c6bs, 3)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 24,
+       "text": [
+        "'hit'"
+       ]
+      }
+     ],
+     "prompt_number": 24
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6bs.find('e', 13)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 25,
+       "text": [
+        "28"
+       ]
+      }
+     ],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len(c6bs) / 978"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 26,
+       "text": [
+        "1.6083844580777096"
+       ]
+      }
+     ],
+     "prompt_number": 26
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6bs[55:60]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 27,
+       "text": [
+        "'bnrrt'"
+       ]
+      }
+     ],
+     "prompt_number": 27
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[(c6bs[0] + c6bs[i] + c6bs[2*i] + c6bs[3*i], i) for i in range(int(len(c6bs) / 3)) if c6bs[i] == 'e' and c6bs[2*i] == 'i' ]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 28,
+       "text": [
+        "[('heih', 177), ('heit', 207), ('heip', 307), ('heil', 522)]"
+       ]
+      }
+     ],
+     "prompt_number": 28
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[c for c in chunks(c6bs, 522)]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 29,
+       "text": [
+        "['hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnrotel',\n",
+        " 'etpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvna',\n",
+        " 'iaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrteb',\n",
+        " 'ltllgfo']"
+       ]
+      }
+     ],
+     "prompt_number": 29
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c6b"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 30,
+       "text": [
+        "'HITHH NFRFE RTEAO FFTNA SLTYO RRREQ THIMS ERULR HFSET AEEIU IWSIH BNRRT SIOII ENIRH MRPYT DTOEI RCITA LNBRP NHTOH ORLIE WTSHT ESPOS OTOYN UWHRE DHHCP ICMNO OTAHA SHTIJ EANET OFRNE USRAG MXURT TOWLE ATBRT EPPTR AAESE NETHH RISNR STSTR NFLDO GHAUM GSESE AKUNT IAHYT TNYUN TNNVH IGWLE WFIAP ASREL FAIEB APCMC PLAHE THTOL HWSUL ADSEU VEAEO TAEUT ATEEF EHLBH TRSHG ATLIA CEEHT RNHGA ASIET UFNNP UREHR ELITT MUDYI NNUEG ICOUE NDEEI AHSUE LHTNO AHTIE AINYF DNIAU OENAT IYEFO HEDAL UAROE RYHUR AERAT ERAHI AONGT WISWS AITBU LTAOM XLETO REOTO TONAO ORTGB CVAIP NLEEW FYRTA EOADU WWETR RTNLR PFPAI ELLRI MNTRO WIEQR ECUAR NDOTA FNROT ELETP ENRPM SHNDD ETDEW HEFOY PEDEN NSNEE GTATE EANES ERTGD LUEOS RBURO WHDGB RPAHE NYTTE KRERT RRHNF NEDOL TSWSI ANIYP OTHMO UOCTY EIEEP ONHKR NNTAI RLTEE IUREM NITAP HOEAO HHNOU UMTKV SENED EEOID PWKIE GTIII OSENH UUFAN BEUIT HRAER HIEEH UAYAS RUSIW GADSI SITRL GFPHI LTWII SIHES URMRO MACEI SOILV DEOEL USAIR IDEOT NFIES OBNTS APOFG SODRT FIRPL TANET RLYIO SOTYO ESSFN TPHEA IGEAO RAIEI TDMTA AEGRH YASRR CFELR TLEEA NEHVE HIVMH NASSI EROIX LMPSJ TTESO FBMRH NDIOC HECNB TTNCO MPUSE SOEHT ENETF IENOO TNWOO TEERI LTOIG DOSME HOIFM LROEF FDTUE SOFLE RWIIY QDBZO TTNRF ANTDI GONTA LAEPD SHEAM NTHLP SNBTU OAHAA LPLEM NPDRS HVNAI AELNH CALIS KACDO AEDTJ GHOIE ADGWA YNDET ENHEG EEUEO EEDNO RYYRF CTEMT TWNTG DETAS UOOOT FWYMI HRGRH OESIN RRAOF RETFE NPOYA ISSES STNHH AYEUL HIWPC TEATU APEAN LUEEL WAHAO ELURE SNBII EASAE TEAGC DCSOR EPSRO ENSEL VOSED UDSIT LTEIT TFSEO ESNLN GINOE RNTEI EIWWL WHTEI RSIIL HTDSR NDESR FHRNT LGRSU ASEDA DOYTA SADUT ENWIT CNAME TERTP OESYT OTOCN YUTSO GCMUD LPADL EADOT EFDSB FELEA HAXRS ONIDT IEIPR ASHIC DCSHI PBIEL SLNAL HORFR ENTAT ORAIE MKLAG RETMR DCWSN AYNWS VNULD OREKU TNNOU TIIUN NHVNI EILOH LTEFN AEATU IFTTA CETLN NRBHB EGLOS NAONM IFKOA RONSN VNFRE TRCFT HDETP SWSUC PERCW TPOAW FHDAY ISOOA GOAEL NDFIG NGRTE BLTLL GFO\\n'"
+       ]
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[i for i in range(len(c6bs)) if c6bs[i] == 'q']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 42,
+       "text": [
+        "[29, 503, 985]"
+       ]
+      }
+     ],
+     "prompt_number": 42
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join([c[0] for c in every_nth(c6bs, 11)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 32,
+       "text": [
+        "'hithhnfrfer'"
+       ]
+      }
+     ],
+     "prompt_number": 32
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join([c[0] for c in every_nth(c6bs, 13)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 33,
+       "text": [
+        "'hithhnfrferte'"
+       ]
+      }
+     ],
+     "prompt_number": 33
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join([c[0] for c in chunks(c6bs, 121)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 34,
+       "text": [
+        "'hhrnrnumeodti'"
+       ]
+      }
+     ],
+     "prompt_number": 34
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "''.join([c[0] for c in chunks(c6bs, 13)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 35,
+       "text": [
+        "'harrseehthoexttnsneitetghuydoihuouocttiuedeeerrsohiaeefhifsiitiohtreiehseiiszomhhihtdtoeentencsllilrdieodhpbrlakhntnsdwon'"
+       ]
+      }
+     ],
+     "prompt_number": 35
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'l' in ''.join([c[0] for c in chunks(c6bs, 13)])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 36,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 36
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "every_nth(c6bs, 11)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 38,
+       "text": [
+        "['httmtbnoreohaegaasdetgrmlvtshtenenfiargurredrmcrpwnaegennckehmoinhutioddnrtegmranmmneieseetoetmaaoeoceyiesieaidnseewtrdtttmoaicnagariounanfcfor',\n",
+        " 'ieysaniepwthhtmtenoanwecheehtulueodyratleteupnuomhsnobkeitriotiibisrimeettrsetrnaprbseemfrtnaunecitettmnntwaoecsiorhdnaeeouthesatryeuhirostphat',\n",
+        " 'taoeerrintocaoxbsrgkyllpwaegrfieianeotwtogwwftatsenesrrdyynuekdoeeilsaoosflsaacesshtonrefwntmopldeeeeairpnpneasetentstdnrcdeaihloenknlfbnnhedee',\n",
+        " 'horrerhrhsypsfureshuueflsefanntgahifeeiatbfwprrehfesrpeopenravpsuewgicetaiyfoafhsjnteoihdiranadnoandmshrohcllsollsterlowtnlfxpihrtwuntthmvdralb',\n",
+        " 'hfruitmcthnihrrtntannwaauoethntihtaorrsoocyeaonlnoeebarloiteosweihgfhelnprinreevitdnholotiflthrhadhnturayhtuuarvtneingyipypdrrpoamsthetbinecynl',\n",
+        " 'nfrlusriotuctnteesuttfihlthlgpmcsiuhyawmtvrtiwdedygruhttteamhekntuapeiufopotagleetictttiuyaahascegeotogoaaeereeoelirdrttouassabrirvnvfaefftwidt',\n",
+        " 'fteriipthewmietpttminieeaaliauuoueoehhsxoatreiotdpttrersheinhnihhadhsssiflspirrhreooenofeqnelahadwgrworfiyaeetpsinesesacetdbosifednnnncgkrptsfl',\n",
+        " 'rnqhwoyaoshnjuophrganabtdebaardueaeduialniarletpeeagonrwmprineeurysiuoaegtohehtioscmnwimsdtpplvltaeynohrsetlsesetgiisusnsslfnhermcuoiaeloespoil',\n",
+        " 'fatfsitlrproeswthnshvpahsuhcseyelinaraieapetlqaetdtdwyhsooltodguaailriissateiylviohpeoglobddspnijyeyttoesuuwnardtiwiraaayoeeiilekwlueetoatwoogg',\n",
+        " 'eshsiidnloeoarlrrfeyhaptetteihinhnalaottononrrfndeelhtniuntauetfesstmlroonyataemxfeutodrfzisnlasgnurgfetelaabgoufnwlfsdmtgaldcsnlsdtialsrrsaanf',\n",
+        " 'rliehetbisdtnaeailstiscouareerndtytuenboolalienreneudtfaohepueiarriwrvibdeoidsehlbcsftoologhbeikhdefdwsfshphicedsolhheueocdetdltanoiltnnocuwggo']"
+       ]
+      }
+     ],
+     "prompt_number": 38
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "every_nth(c6bs, 143)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 64,
+       "text": [
+        "['hetuehroera',\n",
+        " 'iteloirnnny',\n",
+        " 'toetsectptn',\n",
+        " 'hffarefaolw',\n",
+        " 'hreobhelygs',\n",
+        " 'nnhmuulaarv',\n",
+        " 'felxrareisn',\n",
+        " 'rubloytpsuu',\n",
+        " 'fshewaldsal',\n",
+        " 'ertthsesesd',\n",
+        " 'rarodrehseo',\n",
+        " 'tgsrguaesdr',\n",
+        " 'emhebsnatae',\n",
+        " 'axgoriemndk',\n",
+        " 'ouatpwhnhou',\n",
+        " 'frtoagvthyt',\n",
+        " 'ftlthaehatn',\n",
+        " 'ttioedhlyan',\n",
+        " 'noannsipeso',\n",
+        " 'awcayivsuau',\n",
+        " 'sleotsmnldt',\n",
+        " 'leeotihbhui',\n",
+        " 'tahretntiti',\n",
+        " 'ytttkrauweu',\n",
+        " 'obrgrlsopnn',\n",
+        " 'rrnbegsacwn',\n",
+        " 'rthcrfihtih',\n",
+        " 'regvtpeaetv',\n",
+        " 'epaarhraacn',\n",
+        " 'qpairioltni',\n",
+        " 'ttsphlipuae',\n",
+        " 'hrinntxlami',\n",
+        " 'iaelfwlepel',\n",
+        " 'matenimmeto',\n",
+        " 'seueeipnaeh',\n",
+        " 'esfwdsspnrl',\n",
+        " 'renfoijdltt',\n",
+        " 'unnylhtrupe',\n",
+        " 'leprtetseof',\n",
+        " 'rtutsseheen',\n",
+        " 'hhrawusvlsa',\n",
+        " 'fheesronwye',\n",
+        " 'srhoimfaata',\n",
+        " 'eiraarbihot',\n",
+        " 'tsednomaatu',\n",
+        " 'anluimreooi',\n",
+        " 'eriwyahlecf',\n",
+        " 'estwpcnnlnt',\n",
+        " 'itteoedhuyt',\n",
+        " 'usmttiicrua',\n",
+        " 'iturhsoaetc',\n",
+        " 'wrdrmoclsse',\n",
+        " 'snytoihinot',\n",
+        " 'ifinulesbgl',\n",
+        " 'hlnlovckicn',\n",
+        " 'bdnrcdnaimn',\n",
+        " 'nouptebceur',\n",
+        " 'rgefyotdadb',\n",
+        " 'rhgpeetoslh',\n",
+        " 'taiailnaapb',\n",
+        " 'sucieuceeae',\n",
+        " 'imoeesodtdg',\n",
+        " 'ogulpamtell',\n",
+        " 'iseloipjaeo',\n",
+        " 'ienrnruggas',\n",
+        " 'esdihishcdn',\n",
+        " 'neemkdeodoa',\n",
+        " 'iaenresicto',\n",
+        " 'rkitnooesen',\n",
+        " 'huarnteaofm',\n",
+        " 'mnhotnhdrdi',\n",
+        " 'rtswaftgesf',\n",
+        " 'piuiiiewpbk',\n",
+        " 'yaeerenasfo',\n",
+        " 'thlqlseyrea',\n",
+        " 'dyhrtotnolr',\n",
+        " 'ttteebfdeeo',\n",
+        " 'otncenienan',\n",
+        " 'enouitetshs',\n",
+        " 'iyaausneean',\n",
+        " 'ruhrraonlxv',\n",
+        " 'cntnepohvrn',\n",
+        " 'itidmoteosf',\n",
+        " 'tneonfngsor',\n",
+        " 'anatigweene',\n",
+        " 'lviatsoedit',\n",
+        " 'nhnfaoouudr',\n",
+        " 'biynpdtedtc',\n",
+        " 'rgfrhreosif',\n",
+        " 'pwdooteeiet',\n",
+        " 'nlntefretih',\n",
+        " 'heieaiidlpd',\n",
+        " 'twalorlntre',\n",
+        " 'ofuehptoeat',\n",
+        " 'hiothlorisp',\n",
+        " 'oaepntiyths',\n",
+        " 'rpneoagytiw',\n",
+        " 'laanundrfcs',\n",
+        " 'istrueofsdu',\n",
+        " 'eripmtscecc',\n",
+        " 'weymtrmtosp',\n",
+        " 'tleskleeehe',\n",
+        " 'sffhvyhmsir',\n",
+        " 'haonsiotnpc',\n",
+        " 'tihdeoitlbw',\n",
+        " 'eeednsfwnit',\n",
+        " 'sbdeeomngep',\n",
+        " 'paatdtltilo',\n",
+        " 'opldeyrgnsa',\n",
+        " 'scueeoodolw',\n",
+        " 'omawoeeeenf',\n",
+        " 'tcrhisftrah',\n",
+        " 'opoedsfanld',\n",
+        " 'ylefpfdstha',\n",
+        " 'narowntueoy',\n",
+        " 'uhyyktuoiri',\n",
+        " 'wehpipeoefs',\n",
+        " 'htueehsoiro',\n",
+        " 'rhrdgeotweo',\n",
+        " 'etaetaffwna',\n",
+        " 'doeniilwltg',\n",
+        " 'hlrnigeywao',\n",
+        " 'hhasiermhta',\n",
+        " 'cwtnoawitoe',\n",
+        " 'pseesoiherl',\n",
+        " 'iureeririan',\n",
+        " 'clagnaygrid',\n",
+        " 'mahthiqrsef',\n",
+        " 'ndiauedhimi',\n",
+        " 'osatuiboikg',\n",
+        " 'oeoeftzelln',\n",
+        " 'tuneadoshag',\n",
+        " 'avganmtitgr',\n",
+        " 'hetnbttndrt',\n",
+        " 'aaweeanrsee',\n",
+        " 'seisuarrrtb',\n",
+        " 'hoseiefanml',\n",
+        " 'ttwrtgaodrt',\n",
+        " 'iasthrnfedl',\n",
+        " 'jeagrhtrscl',\n",
+        " 'euidayderwg',\n",
+        " 'attleaitfsf',\n",
+        " 'nabursgfhno']"
+       ]
+      }
+     ],
+     "prompt_number": 64
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[(q, u) for q in [i for i in range(len(c6bs)) if c6bs[i] == 'q'] for u in [i for i in range(len(c6bs)) if c6bs[i] == 'u'] if abs(q-u) < 13]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 44,
+       "text": [
+        "[(29, 37), (503, 507), (985, 973)]"
+       ]
+      }
+     ],
+     "prompt_number": 44
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "every_nth(c6bs, 13)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 54,
+       "text": [
+        "['harrseehthoexttnsneitetghuydoihuouocttiuedeeerrsohiaeefhifsiitiohtreiehseiiszomhhihtdtoeentencsllilrdieodhpbrlakhntnsdwon',\n",
+        " 'iorhiniterttuehfeywehueagrieaaernltvanmalddeoptwukuongaiwpuldsrsedrheseenlfoonnavsoenwtsnhelbdetnwhnotsgoarieayuvalanetog',\n",
+        " 'tfefhiroseaorphlaufbtvetaenehudagtoaelnreeeasarsorrhetneghrveapoamcvrocsotmftttankinonfiphawiclegwttycyctxaengntnenovtpar',\n",
+        " 'hfqsbrchpdhftprdkniaoeflahnitoaetatiortnttnnrhricnehdibeaimdopltitfeofnooolltahlaaehrtwnoataisviildltntmersltrwniannnpogt',\n",
+        " 'httenhiooharttioutaplaeisruaielrwoopaprdpdnebehatnmneiehdlretotygaehibbetirenllpicaeygyryyuheootnwsgaaoufshsaesnetrmfsaoe',\n",
+        " 'nnhtrmtrshsnorsgnnpchehaieehenuaimnndfooeessunnnytnoeiuustoonfaoealixmthngorrapladdgydmraeaaarstohrrsmtddoilttvoiubirwwab',\n",
+        " 'faiarralochewanhtnamwolcelgsaaatsxalupwtnwneryfieaiuooiaiwmefgneaervlrttwdewfeseeogereiaiuposeefetnsaeolsncnomnulihfesfel',\n",
+        " 'rsmetplitptularaivscstbetiiuitrewloewaiarherotnyiituistysialisesogtmmhneoofiapnmlawefthosleeapdsredudtcpbidarrutofbktuhlt',\n",
+        " 'flsesyneoiiseesuahrpuaheutceniorseoewiefpeetwteperamdehaiicueotsrrlhpncnosfindbnneaucarfshalesuenieauenafdcladlihteorcdnl',\n",
+        " 'eteiitbwycjrastmhiellethftolyyeaatrweeqnmfgghedoelptpnrstsessdrfahensdoetmdytstphdyetsgreinutrdotrsstrydetshicdiltgacpadl',\n",
+        " 'ryruodrtnmeatesgyglaaurtnmuhferhiotftlrrsotddkotpthkwharriiaorlniyeajimteetqdhudctnoeureswlreoseesreetullihoewoutalrfeyfg',\n",
+        " 'touiitpsunagbntstwfhdtsrnuetdfyitrgyrleohyalgrlhoeovkueulhsibtyteaastopfehudieorajdemohtspueaeisiifdnpteeeirmsrnecootriif',\n",
+        " 'erlwionhwonmreretlaesahnpdnnnohabebrrrctnptubetmneesiursgeornfipisnstcuiroebgaaslgeetooftcesgntneihawosaaipfknenfesnhcsgo']"
+       ]
+      }
+     ],
+     "prompt_number": 54
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[''.join(transpose(l, (3, 11, 0, 1, 2, 4, 5, 6,7, 8, 9, 10, 12))) for l in chunks(c6bs, 13)]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 61,
+       "text": [
+        "['hthithnfrfere',\n",
+        " 'foaoftnasltyr',\n",
+        " 'qurrethimserl',\n",
+        " 'sirhfetaeeiuw',\n",
+        " 'bisihnrrtsioi',\n",
+        " 'rtenihmrpytdo',\n",
+        " 'cpeiritalnbrn',\n",
+        " 'hshtoorliewth',\n",
+        " 'putesosotoynw',\n",
+        " 'dnhrehhcpicmo',\n",
+        " 'haotaashtijen',\n",
+        " 'fgetorneusram',\n",
+        " 'tbxurtowleatr',\n",
+        " 'pnteptraaesee',\n",
+        " 'rtthhisnrstsr',\n",
+        " 'dsnfloghaumge',\n",
+        " 'ktseauntiahyt',\n",
+        " 'nwnyutnnvhigl',\n",
+        " 'ifewfapasrela',\n",
+        " 'ahiebpcmcplae',\n",
+        " 'odthtlhwsulas',\n",
+        " 'eteuvaeotaeua',\n",
+        " 'fsteeehlbhtrh',\n",
+        " 'lrgatiaceehtn',\n",
+        " 'anhgasietufnp',\n",
+        " 'huurerelittmd',\n",
+        " 'neyinuegicoun',\n",
+        " 'itdeeahsuelhn',\n",
+        " 'tdoahieainyfn',\n",
+        " 'ofiauenatiyeo',\n",
+        " 'ayhedluaroerh',\n",
+        " 'eiurarateraha',\n",
+        " 'ttongwiswsaib',\n",
+        " 'arultomxletoe',\n",
+        " 'tgotoonaoortb',\n",
+        " 'iycvapnleewfr',\n",
+        " 'ortaeaduwwetr',\n",
+        " 'rltnlpfpaielr',\n",
+        " 'teimnrowieqrc',\n",
+        " 'nouardotafnrt',\n",
+        " 'thelepenrpmsn',\n",
+        " 'tyddedewhefop',\n",
+        " 'naedensneegtt',\n",
+        " 'nleeaesertgdu',\n",
+        " 'rgeosburowhdb',\n",
+        " 'hrrpaenytteke',\n",
+        " 'rlrtrhnfnedot',\n",
+        " 'ihswsaniypotm',\n",
+        " 'coouotyeieepn',\n",
+        " 'nehkrntairlte',\n",
+        " 'eoiurmnitaphe',\n",
+        " 'hvaohnouumtks',\n",
+        " 'dkeneeeoidpwi',\n",
+        " 'iuegtiiosenhu',\n",
+        " 'befaneuithrar',\n",
+        " 'euhiehuayasrs',\n",
+        " 'aliwgdsisitrg',\n",
+        " 'ihfphltwiisie',\n",
+        " 'mssurromaceio',\n",
+        " 'diilveoelusar',\n",
+        " 'obidetnfieson',\n",
+        " 'pttsaofgsodrf',\n",
+        " 'lyirptanetrli',\n",
+        " 'ttosoyoessfnp',\n",
+        " 'ieheageaoraii',\n",
+        " 'tatdmaaegrhys',\n",
+        " 'farrcelrtleen',\n",
+        " 'esehvhivmhnas',\n",
+        " 'otierixlmpsjt',\n",
+        " 'foesobmrhndic',\n",
+        " 'nphecbttncomu',\n",
+        " 'ofsesehteneti',\n",
+        " 'oeenotnwooter',\n",
+        " 'ohiltigdosmeo',\n",
+        " 'luifmroeffdte',\n",
+        " 'ldsoferwiiyqb',\n",
+        " 'tizotnrfantdg',\n",
+        " 'aeontlaepdsha',\n",
+        " 'homntlpsnbtua',\n",
+        " 'lrhaaplemnpds',\n",
+        " 'aahvniaelnhcl',\n",
+        " 'ajiskcdoaedtg',\n",
+        " 'edhoiadgwayne',\n",
+        " 'hetenegeeueoe',\n",
+        " 'rmdnoyyrfctet',\n",
+        " 'totwngdetasuo',\n",
+        " 'whotfymihrgro',\n",
+        " 'ntesirraofref',\n",
+        " 'osenpyaissest',\n",
+        " 'apnhhyeulhiwc',\n",
+        " 'tuteauapeanle',\n",
+        " 'aeelwhaoelurs',\n",
+        " 'ianbieasaeteg',\n",
+        " 'secdcorepsron',\n",
+        " 'viselosedudst',\n",
+        " 'isltettfseoen',\n",
+        " 'iilngnoerntee',\n",
+        " 'liiwwwhteirsi',\n",
+        " 'dflhtsrndesrh',\n",
+        " 'ldrntgrsuasea',\n",
+        " 'tndoyasadutew',\n",
+        " 'npitcameterto',\n",
+        " 'ttesyotocnyus',\n",
+        " 'meogcudlpadla',\n",
+        " 'eedotfdsbfela',\n",
+        " 'rehaxsonidtii',\n",
+        " 'siprahicdcshp',\n",
+        " 'lrbieslnalhof',\n",
+        " 'tmrenatoraiek',\n",
+        " 'rslagetmrdcwn',\n",
+        " 'wraynsvnuldoe',\n",
+        " 'nnkutnoutiiun',\n",
+        " 'iehvneilohltf',\n",
+        " 'acnaetuifttae',\n",
+        " 'notlnrbhbegls',\n",
+        " 'nonaomifkoarn',\n",
+        " 'ntsnvfretrcfh',\n",
+        " 'prdetswsucpec',\n",
+        " 'oiwtpawfhdays',\n",
+        " 'giooaoaelndfg',\n",
+        " 'tfngrebltllgo']"
+       ]
+      }
+     ],
+     "prompt_number": 61
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/challenge7.ipynb b/challenge7.ipynb
new file mode 100644 (file)
index 0000000..d7d18f4
--- /dev/null
@@ -0,0 +1,321 @@
+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from cipherbreak import *\n",
+      "with open('2013/mona-lisa-words.txt') as f:\n",
+      "    mlwords = [line.rstrip() for line in f]\n",
+      "mltrans = collections.defaultdict(list)\n",
+      "for word in mlwords:\n",
+      "    mltrans[transpositions_of(word)] += [word]\n",
+      "c7a = open('2013/7a.ciphertext').read()\n",
+      "c7b = open('2013/7b.ciphertext').read()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c1a = open('2013/1a.ciphertext').read()\n",
+      "c1b = open('2013/1b.ciphertext').read()\n",
+      "c2a = open('2013/2a.ciphertext').read()\n",
+      "c2b = open('2013/2b.ciphertext').read()\n",
+      "c3a = open('2013/3a.ciphertext').read()\n",
+      "c3b = open('2013/3b.ciphertext').read()\n",
+      "c4a = open('2013/4a.ciphertext').read()\n",
+      "c4b = open('2013/4b.ciphertext').read()\n",
+      "c5a = open('2013/5a.ciphertext').read()\n",
+      "c5b = open('2013/5b.ciphertext').read()\n",
+      "\n",
+      "p1a = caesar_decipher(c1a, 8)\n",
+      "p1b = caesar_decipher(c1b, 14)\n",
+      "p2a = affine_decipher(c2a, 3, 3, True)\n",
+      "p2b = caesar_decipher(c2b, 6)\n",
+      "p3a = affine_decipher(c3a, 7, 8, True)\n",
+      "p3b = keyword_decipher(c3b, 'louvigny', 2)\n",
+      "p4a = keyword_decipher(c4a, 'montal', 2)\n",
+      "p4b = keyword_decipher(c4b, 'salvation', 2)\n",
+      "p5a = keyword_decipher(c5a, 'alfredo', 2)\n",
+      "p5b = vigenere_decipher(sanitise(c5b), 'florence')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(frequencies(sanitise(c7a)))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stderr",
+       "text": [
+        "/usr/local/lib/python3.3/dist-packages/matplotlib/figure.py:372: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+        "  \"matplotlib is currently using a non-GUI backend, \"\n"
+       ]
+      },
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\n3n777S6nGT16dMDPxe9//3vl5OQoJydHy5Yt67aXQLe1b24/3b12tbW1GjVqlEpLS5WTk6O6ujqf\ntUePHtXll1+uvLw85eTkaNWqVT5rFy5cqE8++UT5+flasGCBz7qTPXxz9LtkyRItWrSoy9pf/epX\npwSfrz0MDz/8sP7whz9Ikm6//XYVFRVJkjZt2qTrr7/+tPq3335bubm5am9v19GjR5Wdna2ampou\ne7j//vtPeb3uuecePfbYYz7X709/+pPy8/OVn5+vESNG6JJLLvFZ2yeF8zTzWNfc3GxZlmW1tbVZ\n2dnZ1ueff95l3d69ey2bzWa98cYblmVZVllZmbVkyZIua99//30rMzPTO6+Ty+jKtm3brJycHOvY\nsWPW4cOHrZEjR1pLly7tsrampsaaPn26dfz4ccuyLOu2226zVqxY4Xf90tPTfa7TSdXV1VZeXp7V\n3t5utba2WhkZGT572Lt3rxUXF2ft3LnTsizLKikpsV544QW/8x80aJDfx0OZZu/evVZ2drb10Ucf\nWfn5+dZ7773Xo3meXK/333/f6uzstMaNG2eVlZVZlmVZa9assWbMmOFzmkCei5Ovc1tbm3XkyBFr\nzJgx1o4dO3z2Eui2Fsz2c3Le/fr1s9566y2fNSetXr3auvnmm72/Hzp0yGdtbW2tlZ2d3e08T/bw\nzdolS5ZY5eXlXdbu2LHDmjJlivd3h8Nh1dXVnVa3detWa9asWZZlWdb3v/99a8KECdZXX31llZeX\nW0899VSX87733nutO++80/rpT3962kdrvqm2ttYqKCiwLMuyOjo6rPPPP9/ve/qkr776yiosLLTW\nrVvXbW1fwggqjJYtW6a8vDxNnDhRdXV1+ve//+2zdtiwYZo4caIk6frrr9eWLVu6rNu0aZNKSko0\ndOhQSVJiYqLPeb722muaOXOmBgwYoMGDB+uKK67wudtl48aNeuedd3TBBRcoPz9fmzZt0t69ewNd\nVZ9ef/11zZgxQ/3799egQYM0ffp0v7t+RowYobFjx0qSxo0bp9ra2h73EIpPP/1UM2bM0IsvvhiW\n44MjRozQmDFjZLPZNGbMGE2dOlWSlJ2d7XMdA30utmzZopkzZ+qcc87RwIEDNXPmTL322ms+ewl0\nWwtm+zlp+PDhGj9+vN8aSRo7dqw2bNighQsXasuWLUpISPBZ290yQ5WXl6dPP/1UDQ0N2rlzpxIT\nE5Wamnpa3ckRdGtrqwYMGKCJEydq27Zt2rJliwoLC7uc93333af169dr27Ztmj9/vs8ehg8frqSk\nJL377rtav369CgoK/L6nT/r5z3+uoqIiXX755YGvcB8Q1tPMY5nH49HGjRu1detWDRgwQBdffLHa\n29t91n/zGIZlWT6PadhstoDfsP9b2910paWlWrx4cUDzDlSwPZx99tnen8866yy/u58iaciQIRo+\nfLhee+01ZWVl9Xh+31yvfv36qX///t6fjx8/3u00/p6Lrp5jf8fEQt3WAtnuBg4c2G2NJGVkZGjH\njh165ZVXdO+996qoqEi//vWvA5rWn7i4uFN2TXe3/cyaNUurV69WY2Ojrr322i5r4uPjNWLECD3/\n/POaNGmSxo4dq02bNunjjz/2uW189tlnOnr0qDo6OnTs2DGde+65Pnu46aab9Nxzz6mpqUllZWXd\nruPzzz+v/fv3x+RxOUZQYXL48GElJiZqwIAB+uijj7R161a/9fv27fPWvPjiiz7/Z3bJJZfo73//\nu5qbmyXJ+29XLrroIlVWVuqLL75Qa2ur1q1b5/OPUVFRkVavXq3//ve/3vnu27ev2/XszuTJk/Xy\nyy+rvb1dR44c0SuvvBIVJxT0799f//jHP7RixQqtXLmyt9vxq7CwUJWVlTp27JiOHj2qyspKn9uP\nFPi2Fsz2E6yGhgYNGDBA1113ne68805t377dZ+3gwYPV2toa0Hztdrs+/fRTNTc3q729XevWrfNb\nf80112jlypVavXq1Zs2a5bOusLBQS5Ys0ZQpU1RYWKgnn3xSBQUFPut/8pOf6IEHHtCcOXO6PW52\n5ZVXqqqqStu2bdO0adP81r7zzjtaunRpr56Y1JsYQYXJpZdeqieffFIOh0OjRo3y7lLpis1m06hR\no/T444+rrKxMY8aM0W233dZlrcPh0D333KMpU6borLPOUkFBgZ599tkua/Pz83XNNdcoNzdXycnJ\nfne9jB49Wg888ICKi4vV2dmp+Ph4LV++XN/97nf99t2dCy64QFdccYXGjh0ru92unJwcfetb3wp4\nnt0tI5Q/mIFMY7PZdO6552rdunVyuVwaPHiwfvjDH4Y8T3/r5W8EE8gy8vPzdeONN3pf35tvvlm5\nubk+ewl0W/vf7efCCy/sdhQV6Ouxa9cu3XXXXd7RpL/TyJOSkjR58mTl5OTosssu8/u9cvHx8brv\nvvs0fvx4paamyuFw+O3J4XDoyJEjSktLk91u91lXWFioxYsXa+LEiTrnnHN0zjnn+Az2FStW6Oyz\nz9a1116rzs5OTZo0SR6PR06n02fPl1xyiRITE7t9/h5//HEdPHhQF198sSTpwgsv1FNPPeV3mr6E\nD+oi7I4ePaqBAweqra1NU6ZM0dNPP628vLxe6eXzzz/v1WNbva22tlbTp0/Xrl27gp520aJFGjRo\nkO64444IdBa7Ojs7NW7cOK1evVrnn39+b7djNHbxIexuueUW5efna9y4cbr66qt7LZwOHDigSZMm\n6a677uqV5ZuiJ7vpomH3bDSpqalRRkaGpk6dSjgFgBEUAMBIjKAAAEYioAAARiKgAABGIqAAAEYi\noAAARiKgAABG+j/og6x5jaDpPwAAAABJRU5ErkJggg==\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xb55607cc>"
+       ]
+      }
+     ],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c7af = frequencies(sanitise(c7a))\n",
+      "plot_frequency_histogram(c7af, sort_key=lambda l: c7af[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nf14NDQ0qKSnxO253X4+uar31kZaWph07dujVV1/Vfffdp4KCAv3mN7/xOvYLL7yg/fv3+91H8u0e\n/Pn888919OhRtbW16dixYzr33HO7rIuKiuq0adrb6xYdHa0RI0bohRde0KRJkzR27Fht2rRJn3zy\nSZfrRk/X91mzZmn16tWqr6/Xdddd152nGBI9Wd9Csc57PB5t3LhRW7du1aBBg3TJJZeotbW11+P2\nJ8yggqCgoECrV6/Wf//7X0lSY2Oj9u3b57X+4osvVnl5ub788ks1Nzdr3bp1xu80HThwoP7xj39o\nxYoVWrlyZZ/0sG/fPm3dulWS9NJLL3X51/pJV111lSoqKrRt2zZNmzbN57iTJ0/WK6+8otbWVh05\nckSvvvqq19cjPz9f5eXlOnbsmI4ePary8nKvfdTV1WnQoEG6/vrrddddd2n79u1ee3j33Xe1dOnS\nbh0Ic+mll+rvf/+7GhsbJanjX29++tOf6sEHH9ScOXN87nex2+367LPP1NjYqNbWVq1bt85rbX5+\nvpYsWaIpU6YoPz9fTz31lPLy8rqs7en6fu2112rlypVavXq1Zs2a5fO59VRMTIyam5u7VduT9S0U\nDh8+rLi4OA0aNEgff/xxRy+RhBlUEIwePVoPPvigCgsL1d7erujoaC1fvlznn39+l/W5ubm69tpr\nlZ2drcTERF100UV+/2r359s137zu6/HdDUabzaZzzz1X69atk8vlUkxMjH70ox/1uBd/y/B136hR\no/TEE0+opKREY8aM0e233+61Pjo6Wpdeeqni4uL8Lv/CCy/UlVdeqbFjx8putysrK0vf+c53uqzN\nzc3VTTfd1LFZ9JZbblF2dnaXtbt27dLdd9/dMaP1dXjzE088oYMHD+qSSy6RJF100UV6+umnu6x1\nOBy69957NWXKFJ111lnKy8vTc88912XtihUrdPbZZ+u6665Te3u7Jk2aJI/HI6fTeVptdHS07r//\nfo0fP17JyclyOBw+g3rx4sWaOHGizjnnHJ1zzjle38C/vb7726TscDh05MgRpaSkyG63+6w9qbvr\nWEJCgiZPnqysrCxdfvnlPr+zrifrW0/X+e70e9lll+mpp56Sw+HQqFGjOjY3RhI+qGuARYsWaciQ\nIbrzzjv7upU+88UXXwR12317e7vGjRun1atX64ILLvBbf/ToUQ0ePFgtLS2aMmWKnnnmGeXk5ASl\nF/Q/1dXVmj59unbt2tXXrUQ0NvEZwvRNfKF04MABTZo0SXfffXdQxquqqlJaWpqmTp3arXCSpFtv\nvVW5ubkaN26crrnmGsIJEf07aQpmUAAAIzGDAgAYiYACABiJgAIAGImAAgAYiYACABiJgAIAGOn/\nARTQq3riH9t+AAAAAElFTkSuQmCC\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeb102cc>"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(normalised_english_counts, sort_key=lambda l: normalised_english_counts[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAawAAAEkCAYAAABzKwUZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAHx5JREFUeJzt3X9QVXX+x/HXNSgLpNQxG++lUCF+KF5QkFHXpGwXtXTM\ntJg03aQidx23xmprahNn+1ZMuptGP7CZtXHb3B/ujrjKMq26d0ZLl0zsx6CNFtQFw9rMwF8E18/3\nD4siL+deEMSPPB8zZ7zH8z6f+zmHw33xOefce13GGCMAAM5zvbq7AwAAhIPAAgBYgcACAFiBwAIA\nWIHAAgBYgcACAFghZGCVlZUpKSlJCQkJKiwsPGP5vn37NGbMGPXu3VvLly8/Y3kgEFB6erqmTp3a\nOT0GAPRIEU4LA4GAFi5cqM2bN8vtdiszM1PTpk1TcnJyS03//v31/PPPa/369UHbWLFihVJSUtTQ\n0NC5PQcA9CiOI6zy8nLFx8crLi5OkZGRys3NVUlJSauaAQMGKCMjQ5GRkWesX1NTo9LSUt19993i\n/ckAgLPhGFi1tbWKjY1tmfd4PKqtrQ278QceeEDPPvusevXiUhkA4Ow4JonL5epwwxs3btSVV16p\n9PR0RlcAgLPmeA3L7XbL7/e3zPv9fnk8nrAafuutt7RhwwaVlpbq5MmTqq+v19y5c7VmzZpWdWlp\naXr33Xc70HUAwIXG6/Vqz549wRcaB01NTWbIkCGmqqrKNDY2Gq/XayorK4PWLlmyxCxbtizoMp/P\nZ26++eagy0J0wXpLliyh9jzqB7Xtrz1f+kFtx+tt4pQJjiOsiIgIFRUVKScnR4FAQHl5eUpOTlZx\ncbEkKT8/X3V1dcrMzFR9fb169eqlFStWqLKyUtHR0a3aOpvTiwAAOAaWJE2ePFmTJ09u9X/5+fkt\nj6+66qpWpw2DmTBhgiZMmNDBLgIAIF1UUFBQ0J0dWLp0qbq5C10uLi6O2vOoH9S2v/Z86Qe1Ha+3\nhVMmuL49Z9htXC4XdxECACQ5ZwJvkAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHA\nAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIA\nWIHAAgBYgcACAFiBwAIAWIHAAgBYgcACAFiBwAIAWIHAAgBYIazAKisrU1JSkhISElRYWHjG8n37\n9mnMmDHq3bu3li9f3vL/fr9f119/vYYNG6bhw4dr5cqVnddzAECP4jLGGKeCQCCgxMREbd68WW63\nW5mZmVq7dq2Sk5Nbar744gt98sknWr9+vfr27avFixdLkurq6lRXV6e0tDQdPXpUo0aN0vr161ut\n63K5FKILAIAewikTQo6wysvLFR8fr7i4OEVGRio3N1clJSWtagYMGKCMjAxFRka2+v+rrrpKaWlp\nkqTo6GglJyfr4MGDHd0OAEAPFjKwamtrFRsb2zLv8XhUW1vb7ieqrq5WRUWFsrKy2r0uAPRUMTH9\n5HK5HKeYmH7d3c1zIiJUgcvlOusnOXr0qGbOnKkVK1YoOjr6rNsDgJ6ioeErSc6XTRoazv512gYh\nA8vtdsvv97fM+/1+eTyesJ+gqalJt956q+bMmaPp06cHrSkoKGh5nJ2drezs7LDbBwDYy+fzyefz\nhVUb8qaL5uZmJSYmasuWLRo0aJBGjx59xk0X3ykoKFCfPn1abrowxmjevHnq37+/fv/73wfvADdd\nAECbTp/lCvUaeeG8jjplQsjAkqR//etfuv/++xUIBJSXl6dHH31UxcXFkqT8/HzV1dUpMzNT9fX1\n6tWrl/r06aPKykrt2bNH1113nUaMGNFyavHpp5/WpEmTwuocAPR0BNYPloUTWF2JwAKAthFY3+OT\nLgAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAA\nAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABWILAAAFYgsAAAViCwAABW\nILAAAFYgsAAAViCwAABWILAAAFYgsAAAVggZWGVlZUpKSlJCQoIKCwvPWL5v3z6NGTNGvXv31vLl\ny9u1LgAA4XIZY0xbCwOBgBITE7V582a53W5lZmZq7dq1Sk5Obqn54osv9Mknn2j9+vXq27evFi9e\nHPa6kuRyueTQBQDo0Vwul6RQr5EXzuuoUyY4jrDKy8sVHx+vuLg4RUZGKjc3VyUlJa1qBgwYoIyM\nDEVGRrZ7XQAAwuUYWLW1tYqNjW2Z93g8qq2tDavhs1kXAIAfcwys00PRjjmbdQEA+LEIp4Vut1t+\nv79l3u/3y+PxhNVwe9YtKChoeZydna3s7OywngMAYDefzyefzxdWreNNF83NzUpMTNSWLVs0aNAg\n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\n1CkzatQoM3/+fGOMMSUlJWb69OlntP/dz+47y5YtMwUFBY7bGM6x095js6qqyvTq1cv897//Ddn2\nunXrzD333NMy//XXXzu2GxERYd59911jjDG33Xabee2118669jvh7Atjvj8Ojh8/boYPH97msfTd\nfjt+/Lg5evSoGTZsmKmoqGiz3erq6lY/v7ZUVlaaqVOnmubmZmOMMQsWLDBr1qwJq+8XCkZYXWzR\nokWaOHGibrrppqDLt23bphkzZqh3797q06ePpk2b1qmnUp544gm98cYb2rVrlx5++GHH2s8//1zT\np0/X66+/7njNIC0tTZ9//rk+++wzvfvuu+rbt6/cbneb9bGxsRozZowkac6cOdq+fftZ17755pua\nPn26Lr74YkVHR2vq1Kmdtt+2bt2q2267Tf36nX6Td9++fYPWXXPNNerfv7/27NmjN954QyNHjgxa\n+91otaGhQb1799aYMWO0a9cubd++XePHjz+jfvDgwRo2bJhcLpeGDRumG2+8UZI0fPhwVVdXd8o2\nhqMjx+Y111yj0aNHh2x7xIgR+ve//61HHnlE27dvV0xMjGP94MGDNWLECEnSqFGjHPdDe2rbY8WK\nFUpLS9OYMWNUU1Oj/fv3B63bvn27ZsyYoUsvvVRRUVGaMWOGtm3b1ma74R63W7Zs0TvvvKOMjAyl\np6dr69atqqqq6tC22MrxtnacnVdffVV+v9/x/LTL5Wp1wHZmWEnS//73Px07dkyBQEAnTpzQZZdd\n1mbtFVdcoWuuuUbbtm1TUlKSY7uzZs3SunXrVFdXp9zcXMfaH177MMY4XgsJt7Yr99uP23Zy9913\na/Xq1Tp06JDmz58ftCYyMlKDBw/Wq6++qrFjx2rEiBHaunWrDhw4EHQ/X3LJJS2Pe/XqpYsvvrjl\ncXNz8xn1ERERrU4NOZ1GbY+O7OOoqKiw2k5ISFBFRYU2bdqkxx9/XBMnTtRvfvObNut/uE8uuugi\nx21sT224fD6ftmzZop07d6p37966/vrr1djYGLQ22H7ryDXDYObNm6ennnqqU9qyESOsLvLOO+9o\n+fLlIS/wX3fddVq/fr1OnjyphoYGbdy4sdMObun0e+WefPJJ3XHHHSHPj1988cX6xz/+oTVr1gR9\nk/cP3X777Vq7dq3WrVunWbNmOdZ++umn2rlzpyTp9ddfDzqqaG/tuHHj9M9//lONjY06evSoNm3a\n1Gn77YYbbtDf/vY3HT58WJJa/g3mlltuUVlZmXbt2qWcnJw268aPH69ly5ZpwoQJGj9+vF5++WWN\nHDmyU/o7cOBAff755zp8+LAaGxu1cePGTmm3K4/Nzz77TL1799bs2bP14IMPavfu3Z3Sblepr69X\n37591bt3b+3bt6/lGA1m/PjxWr9+vU6cOKFjx45p/fr1jsd8nz591NDQELIPEydO1Lp16/TFF19I\nOn1cfvrpp+3fGIsxwuoiL7zwgr766itdf/31kqTMzEytWrXqjLr09HTdfvvt8nq9uvLKK5WZmRn2\nX/ehXjzWrFmjSy65RLm5uTp16pTGjh0rn8+n7OzsNtu77LLLtHHjRv30pz9Vnz59dPPNNwetTUlJ\n0dGjR+XxeDRw4EDHPiYmJuqFF17Q/PnzNWzYMC1YsKDN+nBrMzIyNG3aNI0YMUIDBw5UamqqLr/8\n8rZ3hsK/yy0lJUWPPfaYJkyYoIsuukgjR47UH/7wh6C1kZGRuuGGG9S3b1/H9sePH6+nnnpKY8aM\n0aWXXqpLL720zRexH7fzw/lgzxEZGaknnnhCo0ePltvtVkpKSshtDWdf/PjYDOdUX7j7+P3339dD\nDz3UMoIMdVu30z45m9pwlkvSpEmT9PLLLyslJUWJiYktp62DSU9P189//vOW/XXPPffI6/W2Wd+/\nf3+NGzdOqampmjJlSpvfHZicnKwnn3xSP/vZz3Tq1ClFRkbqxRdf1NVXXx2y/xcK3jh8nlm6dKmi\no6O1ePFix7ovv/yyU8/Pnw+qq6s1depUvf/++2HVHzt2TFFRUTp+/LgmTJigV155RWlpaV3cy9ZO\nnTqlUaNGad26dRo6dOg5fW6gp+GU4Hko1F98Bw8e1NixY/XQQw+dox6dO+055XTvvfcqPT1do0aN\n0syZM895WFVWViohIUE33ngjYQWcA4ywAABWYIQFALACgQUAsAKBBQCwAoEFALACgQUAsAKBBQCw\nwv8DbMnA/BWkp54AAAAASUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeae5cec>"
+       ]
+      }
+     ],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c7bf = frequencies(sanitise(c7b))\n",
+      "plot_frequency_histogram(c7bf, sort_key=lambda l: c7bf[l])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nZWWllZWVZbW0tFjHjx+3UlJS/K7PMwJ9PTt27LCmTp1qWZZlfe9737NGjRplffXVV1ZJSYn1/PPP\n+3wt77//vtXW1mYNHz7cKi4utizLstavX29NmjTJ5zKTk5P9rsczznymm5ubrRMnTlhDhw61du/e\n7bOmqqrKKigosE6fPm1ZlmXde++91sqVK33WVFdXWzk5OZZlWVZra6s1cODAgP4vtHednlnWN/8v\nhAIjqIvgZz/7mfLy8nTjjTf6bfvaa69p8uTJ6tGjh3r37q2bbrrJ7+6dYcOGafPmzZo3b562b9+u\nmJgYn+2zsrL0ySefqK6uTnv27FFsbKwSExP99u3RRx/Vpk2btHPnTs2ZM8dv+zP69eun0aNHS5Jm\nzJih7du3+2wfzHuwdetWFRYWqm/fvpKk2NhYv/365JNPNGnSJL300kud/l3M4sWLlZWVpdGjR6um\npkb//Oc//db0799fI0eO7NR+tXfdSNKAAQM0bNgwSdLw4cNVXV3ts/3rr7+uSZMmqXv37urVq5cK\nCgoC3mUZqDMj4OPHj6tHjx4aPXq0du7cqe3btys3N/eCdQMGDNDQoUNls9k0dOhQjR8/XpKUnp7u\n93W1x/bt2zV58mRdccUV6tmzpyZPnqzXXnvNZ82WLVv0zjvvaMSIEcrOztbWrVt18OBBnzX9+/dX\nXFyc3n33XW3atEk5OTkB/V9o7zqVFPJ1KIX4MHP4t2LFCh0+fDjgfbU2m+2sFR/IhyAlJUW7d+/W\nK6+8okceeUR5eXn61a9+5bNm6tSpWrdunerr63XbbbcF1LdPP/1UJ0+eVGtrq06dOqUrr7wyoLpv\nfo9gWZbf7xWCeQ/+tyYQffr0Uf/+/fXaa68pLS0toJqoqKizdrMEsrvS4/Foy5Yt2rFjh3r06KHr\nrrtOLS0tfut69uwZUJ86or3rRpIuv/xy7/XLLrvM73sQzPpsr+joaA0YMEArVqzQmDFjNGzYMG3d\nulUff/yxz3X7zdfSrVs3de/e3Xv99OnTIevf+d6DQN7roqIiLViwoF3LuvPOO7V8+XI1NDSouLg4\noJr2rtPOwgiqC73zzjtatGhRu75Evfbaa1VeXq4vvvhCx48f18aNG/1+kOvq6tSjRw/dfvvteuCB\nB7Rr1y6/y7n11lu1evVqrVu3TlOnTg2obz/+8Y/1+OOPa/r06e3a53zo0CHt2LFDkvTSSy/5/ItW\nCu49uP766/XXv/5VjY2NkuT915fu3bvrb3/7m1auXKnVq1cH9Frsdrs++eQTNTY2qqWlRRs3bvRb\nc+zYMcXGxqpHjx766KOPvO+FCdq7boIxduxYvfzyy2ppadGJEyf0yiuvdMrBD7m5uVq4cKHGjRun\n3NxcPffcc8rJyQn5coKRm5ur8vJynTp1SidPnlR5ebnf9zovL0/r1q3Tv//9b0lff6YPHTrkd1k3\n33yzKioqtHPnTk2YMCEk/T+f3r176/jx4yF9TkZQXWjp0qX6/PPPdd1110mSrrnmGj3//PM+a7Kz\ns3XrrbcqMzNT8fHxuuaaa/z+xbl37149+OCD3r8AAzn00+Fw6MSJE0pKSpLdbvfbfuXKlbr88st1\n2223qa2tTWPGjJHH45HT6fRbO3jwYC1dulTFxcUaOnSo7r33Xp/t//c9CGQ3l8Ph0MMPP6xx48bp\nsssuU05Ojl588UWfNTabTVdeeaU2btwol8ul3r176wc/+IHPmujoaD366KMaOXKkEhMT5XA4/G5s\nb7jhBj333HNyOBwaPHiwd5eaP8FsxNtTY7PZ2r1uzrcMf8scMWKEbrrpJg0bNkx2u10ZGRn61re+\nFXAfA5Wbm6sFCxZo9OjRuuKKK3TFFVf4DQFfryWQkX6gsrOzdccdd3g/y3fddZcyMzN91gwZMkSP\nP/648vPz1dbWpujoaJWVlenqq6/2WRcdHa3rr79esbGxAfexvetUkuLi4jR27FhlZGRo4sSJITkf\nID/UvcTMnz9fvXr10v3333+xuxKU6upqFRQUaO/evRe7K7iITp48qZ49e6q5uVnjxo3TsmXLlJWV\ndbG7FZba2to0fPhwrVu3TgMHDrzY3WkXdvFdgkz+LUggLvX+o+PuvvtuZWdna/jw4ZoyZQrh1Emq\nqqqUkpKi8ePHX3LhJDGCAgAYihEUAMBIBBQAwEgEFADASAQUAMBIBBQAwEgEFADASP8PW/f+Q9EK\neawAAAAASUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeb95f8c>"
+       ]
+      }
+     ],
+     "prompt_number": 7
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(c7bf)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nrClTplhHjhyxLMuybr31Vmvp0qVB+8rMzAx6v7+ptrbWKigosNrb260DBw5YWVlZQce2a9cuKyEh\nwdq2bZtlWZZVVlZmPf/880H76tevn+1x7dq1y8rNzbU+/PBDq7Cw0Hr33Xdt19rt59j9eO+996zO\nzk5r1KhRVkVFhWVZlrVy5Upr6tSpAetCuf/HtoG2tjbr4MGD1ogRI6ytW7cGHV+o22c429qxvnr1\n6mW9+eabQdtalmWtWLHCuummm7p+37dvn606v99v5ebm2mp7bFzfbL9w4UKrsrIyYM3WrVutCRMm\ndP3ucrms+vr6U7bftGmTNX36dMuyLOt73/ueNWbMGOurr76yKisrrSeffDJgX/fcc491xx13WD/9\n6U9P+NrPyfj9fquoqMiyLMvq6OiwLrjgAluvIZZlWV999ZVVXFxsrV692lb7YJhBRdnixYtVUFCg\nsWPHqr6+Xv/617+C1gwaNEhjx46VJF133XXauHFjwPbr169XWVmZBg4cKElKTk4O2serr76qadOm\nqU+fPurfv7+uuOKKoLtQ1q1bp7ffflsXXnihCgsLtX79eu3atStoX6F67bXXNHXqVPXu3Vv9+vXT\nlClTbO3eGTJkiEaOHClJGjVqlPx+f8TH9sknn2jq1Kl64YUXeuyzwiFDhmjEiBFyOBwaMWKEJk2a\nJEnKzc0NeJ9Cvf8bN27UtGnTdM4556hv376aNm2aXn311aDjC3X7DGdbO2bw4MEaPXq0rbYjR47U\n2rVrNW/ePG3cuFFJSUm26uyOpTsKCgr0ySefqLGxUdu2bVNycrLS09NP2f7Y7PzAgQPq06ePxo4d\nq82bN2vjxo0qLi4O2Ne9996rNWvWaPPmzZozZ07QsQ0ePFgpKSl65513tGbNGhUVFdl6DZGkn//8\n5yopKdHll19uq30wET3MHIH5fD6tW7dOmzZtUp8+fTRx4kS1t7cHrfvm5xWWZQX9/MLhcIT8n+x/\na+zWl5eXa8GCBSH1Fapwx3b22Wd3/XzWWWfZ2vUUqgEDBmjw4MF69dVXlZOTE/Hbl46/H7169VLv\n3r27fj5y5IitOjv3/2SPs53Pyrq7fYayrfbt29d226ysLG3dulUvv/yy7rnnHpWUlOjXv/617Xq7\nEhISjtu1bXc7mz59ulasWKGmpiZdc801AdsmJiZqyJAheu655zRu3DiNHDlS69ev10cffRR0u/v0\n00916NAhdXR06PDhwzr33HODju3GG2/Us88+q+bmZlVUVNi6P88995z27NkT0c/vmEFF0f79+5Wc\nnKw+ffroww8/1KZNm2zV7d69u6vtCy+8EPQd0yWXXKK//e1vamlpkaSufwO5+OKLVV1drS+++EIH\nDhzQ6tWrg77QlJSUaMWKFfrPf/7T1c/u3bvt3KWQjB8/Xi+99JLa29t18OBBvfzyy8YcZNC7d2/9\n/e9/19KlS7Vs2bLTPZxuKS4uVnV1tQ4fPqxDhw6puro66LYmhb59hrOthaOxsVF9+vTRtddeqzvu\nuENbtmyxVde/f38dOHDAdj9Op1OffPKJWlpa1N7ertWrV9uqu/rqq7Vs2TKtWLFC06dPD9q+uLhY\nCxcu1IQJE1RcXKwnnnhCRUVFQet+8pOf6P7779fMmTNtfaYmHf2svKamRps3b9bkyZODtn/77be1\naNGiiB/4xAwqii699FI98cQTcrlcGjZsWNdukUAcDoeGDRumxx57TBUVFRoxYoRuvfXWgDUul0t3\n3323JkyYoLPOOktFRUV65plnAtYUFhbq6quvVn5+vlJTU23tRhk+fLjuv/9+lZaWqrOzU4mJiVqy\nZInOP//8oPcpFBdeeKGuuOIKjRw5Uk6nU3l5efrWt74VtO5/+wl1NmCHw+HQueeeq9WrV8vj8ah/\n//76wQ9+ENF+At2PQLcT6v0vLCzUDTfc0PXc33TTTcrPzw86vlC3z//d1i666CLbs6hQHrft27fr\nzjvv7Jp12j10PCUlRePHj1deXp4uu+yyoOe1S0xM1L333qvRo0crPT1dLpfL1jhdLpcOHjyojIwM\nOZ3OoO2Li4u1YMECjR07Vuecc47OOeecoG8Gli5dqrPPPlvXXHONOjs7NW7cOPl8Prnd7qD36ZJL\nLlFycrKt+/LYY4/p888/18SJEyVJF110kZ588smgdcHwRV2cEQ4dOqS+ffuqra1NEyZM0FNPPaWC\ngoLTPay45/f7NWXKFG3fvj3s25g/f7769eun22+/PYIjQ3d0dnZq1KhRWrFihS644ILTNg528eGM\ncPPNN6uwsFCjRo3SVVddRTgZJBK750zZZQuprq5OWVlZmjRp0mkNJ4kZFADAUMygAABGIqAAAEYi\noAAARiKgAABGIqAAAEYioAAARvp/fPP9PvjmFnQAAAAASUVORK5CYII=\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeaa372c>"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plot_frequency_histogram(normalised_english_counts)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "iVBORw0KGgoAAAANSUhEUgAAAawAAAEkCAYAAABzKwUZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAH6NJREFUeJzt3X9QVXX+x/HXNSgLpNQxG++lUCF+CF5QkVGXxGwXtXTM\ntJg03bQidx23xmprahNn+1ZOuptGP7CZtXHb3B/ujrjKMq26d0ZLl0zsx6CNFtQF09rMwF8E18/3\nD5Mi4dwLiNwPPh8zd+Rw3+fc9+fciy8+5xzudRljjAAACHM9uroBAABCQWABAKxAYAEArEBgAQCs\nQGABAKxAYAEArBA0sEpLS5WUlKSEhAQtXbr0nPv37dunUaNGqWfPnlq+fPk59wcCAWVkZGjy5Mnn\np2MAwEUpwunOQCCgBQsWaPPmzXK73crMzNSUKVOUnJzcVNO3b1+98MILWr9+fYvbWLFihVJSUlRX\nV3d+OwcAXFQcZ1hlZWWKj49XXFycIiMjlZeXp+Li4mY1/fr104gRIxQZGXnO+tXV1SopKdE999wj\n/j4ZANARjoFVU1Oj2NjYpmWPx6OampqQN/7ggw/queeeU48enCoDAHSMY5K4XK52b3jjxo26+uqr\nlZGRwewKANBhjuew3G63/H5/07Lf75fH4wlpw2+//bY2bNigkpISnTp1SrW1tZo9e7bWrFnTrC49\nPV3vvfdeO1oHAHQ3Xq9Xe/bsaflO46ChocEMGjTIVFZWmvr6euP1ek1FRUWLtYsXLzbLli1r8T6f\nz2duueWWFu8L0oL1Fi9eTG0Y9UFt22vDpQ9q219vE6dMcJxhRUREqLCwULm5uQoEApo3b56Sk5NV\nVFQkScrPz9ehQ4eUmZmp2tpa9ejRQytWrFBFRYWio6ObbasjhxcBAHAMLEmaOHGiJk6c2Ox7+fn5\nTV9fc801zQ4btmTs2LEaO3ZsO1sEAEC6pKCgoKArG1iyZIm6uIVOFxcXR20Y9UFt22vDpQ9q219v\nC6dMcH13zLDLuFwuriIEAEhyzgT+QAoAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUC\nCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsA\nYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBghZACq7S0VElJSUpISNDSpUvPuX/f\nvn0aNWqUevbsqeXLlzd93+/3a9y4cRoyZIhSU1O1cuXK89c5AOCi4jLGGKeCQCCgxMREbd68WW63\nW5mZmVq7dq2Sk5Obar788kt9+umnWr9+vXr37q1FixZJkg4dOqRDhw4pPT1dx44d0/Dhw7V+/fpm\n67pcLgVpAQBwkXDKhKAzrLKyMsXHxysuLk6RkZHKy8tTcXFxs5p+/fppxIgRioyMbPb9a665Runp\n6ZKk6OhoJScn6+DBg+0dBwDgIhY0sGpqahQbG9u07PF4VFNT0+YHqqqqUnl5ubKystq8LjpPTEwf\nuVwux1tMTJ+ubhMAFBGswOVydfhBjh07punTp2vFihWKjo7u8PZw/tTVfS3J+ZBsXV3HXwMA0FFB\nA8vtdsvv9zct+/1+eTyekB+goaFBt912m2bNmqWpU6e2WFNQUND0dU5OjnJyckLePgDAXj6fTz6f\nL6TaoBddNDY2KjExUVu2bNGAAQM0cuTIcy66OKugoEC9evVquujCGKM5c+aob9+++v3vf99yA1x0\n0aXOzKCD7X+eIwAXhlMmBA0sSfrXv/6lBx54QIFAQPPmzdNjjz2moqIiSVJ+fr4OHTqkzMxM1dbW\nqkePHurVq5cqKiq0Z88e3XDDDRo6dGjTocVnnnlGEyZMCKk5dD4CC0A46XBgdSYCq2sRWADCSYcu\nawcAIBwQWAAAKxBYAAArEFgAACsQWAAAKxBYAAArEFgAACsQWAAAKxBYAAArEFgAACsQWAAAKxBY\nAAArEFgAACsQWAAAKxBYAAArEFgAACsQWAAAKxBYAAArEFgAACsQWAAAKxBYAAArEFgAACsQWAAA\nKxBYAAArEFgAACsQWAAAKxBYAAArEFgAACsEDazS0lIlJSUpISFBS5cuPef+ffv2adSoUerZs6eW\nL1/epnUBAAiVyxhjWrszEAgoMTFRmzdvltvtVmZmptauXavk5OSmmi+//FKffvqp1q9fr969e2vR\nokUhrytJLpdLDi2gk7lcLknB9j/PEYALwykTHGdYZWVlio+PV1xcnCIjI5WXl6fi4uJmNf369dOI\nESMUGRnZ5nUBAAiVY2DV1NQoNja2adnj8aimpiakDXdkXQAAfswxsM4cLmqfjqwLAMCPRTjd6Xa7\n5ff7m5b9fr88Hk9IG27LugUFBU1f5+TkKCcnJ6THAADYzefzyefzhVTreNFFY2OjEhMTtWXLFg0Y\nMEAjR45s8cIJ6Uzo9OrVq+mii1DX5aKLrsVFFwDCiVMmOM6wIiIiVFhYqNzcXAUCAc2bN0/Jyckq\nKiqSJOXn5+vQoUPKzMxUbW2tevTooRUrVqiiokLR0dEtrgsAQHs4zrAuSAPMsLoUMywA4aTdl7UD\nABAuCCwAgBUILACAFQgsAIAVCCwAgBUILACAFQgsAIAVCCwAgBUILACAFQgsAIAVCCwAgBUILACA\nFQgsAIAVCCwAgBUILACAFQgsAGEnJqaPXC6X4y0mpk9Xt4kLjA9wvMjxAY4IR7wuL158gCMAwHoE\nFgDACgQWAMAKBBYAwAoEFgDACgQWAMAKBBYAwAoEFgDACgQWAMAKBBYAwAoEFgDACkEDq7S0VElJ\nSUpISNDSpUtbrFm4cKESEhLk9XpVXl7e9P1nnnlGQ4YMUVpamu68807V19efv84BABcVx8AKBAJa\nsGCBSktLVVFRobVr12rv3r3NakpKSnTgwAHt379fq1at0vz58yVJVVVVevXVV7V792598MEHCgQC\n+vOf/9x5IwEAdGuOgVVWVqb4+HjFxcUpMjJSeXl5Ki4ublazYcMGzZkzR5KUlZWlo0eP6vDhw4qJ\niVFkZKROnDihxsZGnThxQm63u/NGAgDo1hwDq6amRrGxsU3LHo9HNTU1IdX06dNHixYt0rXXXqsB\nAwboqquu0k033XSe2wcAXCwcA+vMZ9IE19Jnl3z88cd6/vnnVVVVpYMHD+rYsWP605/+1L4uAZyD\nDznExSbC6U632y2/39+07Pf75fF4HGuqq6vldrvl8/k0evRo9e3bV5I0bdo0vf3225o5c+Y5j1NQ\nUND0dU5OjnJyctozFuCiUlf3tYJ9yGFdXWi/dAJdxefzyefzhVZsHDQ0NJhBgwaZyspKU19fb7xe\nr6moqGhWs2nTJjNx4kRjjDE7duwwWVlZxhhjysvLzZAhQ8yJEyfM6dOnzezZs01hYeE5jxGkBXQy\nSUYyQW48R+GoOz933XlscOb0vDrOsCIiIlRYWKjc3FwFAgHNmzdPycnJKioqkiTl5+dr0qRJKikp\nUXx8vKKiorR69WpJUnp6umbPnq0RI0aoR48eGjZsmO677752JTAAAK7vEq3rGnC5WjwHZqOYmD7f\nHaZpXa9evVVbe+QCdRTcmfOUwfZ/93mOupPu/Nx157HBmVMmEFjnkY0/ZDb2jDO683PXnccGZ06Z\nwFszAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxA\nYAEArEBgAQCsQGABAKxAYAEArEBgAQCsQGABAKxAYAEArEBgwSoxMX3kcrkcbzExfbq6TQCdgMCC\nVerqvpZkHG9nauxEIAOtI7DQ5fhP+nvdPZCBjojo6gaA7/+TdqpxXZhmAIQtZlgAACsQWAAuCA79\noqM4JAjgguDQLzqKGRYAwAoEFgDACkEDq7S0VElJSUpISNDSpUtbrFm4cKESEhLk9XpVXl7e9P2j\nR49q+vTpSk5OVkpKinbu3Hn+OgcAXFQcAysQCGjBggUqLS1VRUWF1q5dq7179zarKSkp0YEDB7R/\n/36tWrVK8+fPb7rvV7/6lSZNmqS9e/fq/fffV3JycueMAgDQ7TkGVllZmeLj4xUXF6fIyEjl5eWp\nuLi4Wc2GDRs0Z84cSVJWVpaOHj2qw4cP65tvvtG2bds0d+5cSVJERISuvPLKThoGAKC7cwysmpoa\nxcbGNi17PB7V1NQEramurlZlZaX69eunu+++W8OGDdO9996rEydOnOf2AQAXC8fAcrlCu8TUmOaX\nqrpcLjU2Nmr37t36xS9+od27dysqKkrPPvts+zsFAFzUHP8Oy+12y+/3Ny37/X55PB7Hmurqarnd\nbhlj5PF4lJmZKUmaPn16q4FVUFDQ9HVOTo5ycnLaOg4AXSAmpk/Q9zbs1au3amuPXKCOYBufzyef\nzxdasXHQ0NBgBg0aZCorK019fb3xer2moqKiWc2mTZvMxIkTjTHG7Nixw2RlZTXdl52dbT766CNj\njDGLFy82jzzyyDmPEaQFq0gykglyC6/xhkPPbekhHPrtTLbti87qNxzGhq7h9Lw6zrAiIiJUWFio\n3NxcBQIBzZs3T8nJySoqKpIk5efna9KkSSopKVF8fLyioqK0evXqpvVfeOEFzZw5U99++60GDx7c\n7D4AANrC9V2idV0DLtc558BsdeacX7CxhNd4w6HntvQQDv12Jtv2RWf1Gw5jQ9dwygTe6QIAYAUC\nCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsA\nYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAFAgsAYAUCCwBgBQILAGAF\n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\nrY7prLKyMpOenm7q6+tNXV2dSUhIaLWHyspKExERYd577z1jjDG33367ef311x23Hx0d7Xh/e9ap\nrKw0qampZt++fSYjI8O8//77Hdrm2XF9+OGH5vTp02b48OFm7ty5xhhjiouLzdSpU1tdJ5R9cfZ5\nPnHihDl27JgZMmSIKS8vb7WXUF9rbXn9nN12jx49zH//+99Wa85at26duffee5uWv/nmm1Zrq6qq\nTGpqatBtnu3hh7XLli0zBQUF59SVl5ebsWPHNi2npKSY6urqFre5c+dOM2PGDGOMMT/5yU9MVlaW\naWhoMAUFBWbVqlUtrvPEE0+Yhx56yPzyl79s8c95zqqqqjLDhg0zxhgTCATM4MGDHX+mjTGmoaHB\nZGdnm40bNzrWdUfMsDrRihUrlJ6erlGjRqm6ulr79+9vtTY2NlajRo2SJM2aNUvbt29vsW7r1q26\n/fbb1afPmT8U7N27d6vb3LZtm6ZNm6aePXuqV69emjJlSquHabZs2aJ3331XI0aMUEZGhrZu3arK\nyspQh9qqt956S1OnTtWll16q6OhoTZ482fFQ0cCBAzV06FBJ0vDhw1VVVdXhHtrjiy++0NSpU/XG\nG2+cl/OLAwcO1JAhQ+RyuTRkyBDddNNNkqTU1NRWxxjqvti+fbumTZumyy+/XFFRUZo2bZq2bdvW\nai+hvtba8vo567rrrtPIkSMdayRp6NCh+ve//61HH31U27dvV0xMTKu1wR6zPdLT0/XFF1/o888/\n13vvvafevXvL7Xa3WHt2hl1XV6eePXtq1KhR2rVrl7Zv367s7OwW13nyySf15ptvateuXXrkkUda\n7eO6665T3759tWfPHr355psaNmyY48+0dObNxsePH6+bb7459AF3E46XtaP9fD6ftmzZop07d6pn\nz54aN26c6uvrW63/4TkQY0yr50RcLlfIP8A/rg223pw5c/T000+HtO1QtbWHyy67rOnrSy65xPFw\nVWe66qqrdN1112nbtm1KSkrq8PZ+OK4ePXro0ksvbfq6sbEx6DpO+6Klfex0Tq29r7VQXndRUVFB\nayQpISFB5eXl2rRpk5544gmNHz9ev/nNb0Ja10lERESzQ9lOr58ZM2Zo3bp1OnTokPLy8lqti4yM\n1MCBA/Xaa69p9OjRGjp0qLZu3aoDBw60+tr43//+p+PHjysQCOjkyZO64oorWt3+Pffco9WrV+vw\n4cOaO3eu4/hee+01+f3+i/acHjOsTlJbW6vevXurZ8+e2rdvn3bu3OlY/9lnnzXVvPHGG63+5nbj\njTfqb3/7m44cOSJJTf+25IYbbtD69et16tQp1dXVaePGja3+5zR+/HitW7dOX375ZdN2P/vss6Dj\nDGbMmDH65z//qfr6eh07dkybNm2y4gKFSy+9VP/4xz+0Zs2aFv/gPZxkZ2dr/fr1OnnypI4fP671\n69e3+vqRQn+tteX101aff/65evbsqZkzZ+qhhx7S7t27W63t1auX6urqQtpu//799cUXX+jIkSOq\nr6/Xxo0bW6294447tHbtWq1bt04zZsxw3G52draWLVumsWPHKjs7W6+88oqGDRvWan1+fr6eeuop\n3XnnnUHPu916660qLS3Vrl27lJub22rdu+++q+XLl3fpRU5djRlWJ5kwYYJeeeUVpaSkKDExsekQ\nTEtcLpcSExP14osvau7cuRoyZIjmz5/fYm1KSooef/xxjR07VpdccomGDRumP/zhDy3WZmRk6I47\n7pDX69XVV1/teKgmOTlZTz31lH72s5/p9OnTioyM1EsvvaRrr73Wse9gRowYoSlTpmjo0KHq37+/\n0tLSdOWVV4a8zWCP0Z7/QENZx+Vy6YorrtDGjRv105/+VL169dItt9zS7m06jctphhPKY2RkZOjn\nP/950/N77733yuv1ttpLqK+1H79+MjMzg86yQn0+PvjgAz388MNNs02ny9b79u2rMWPGKC0tTZMm\nTXL8bL3IyEg9+eSTGjlypNxut1JSUlrtKSUlRceOHZPH41H//v0d+83OztbTTz+tUaNG6fLLL9fl\nl1/eatCvWbNGl112mfLy8nT69GmNHj1aPp9POTk5rfZ84403qnfv3o7778UXX9TXX3+tcePGSZIy\nMzO1atUqx767G/5wGJ3u+PHjioqK0okTJzR27Fi9+uqrSk9P75Jevvrqqy49N9bVqqqqNHnyZH3w\nwQdtXnfJkiWKjo7WokWLOqGzi9fp06c1fPhwrVu3ToMHD+7qdsIahwTR6e677z5lZGRo+PDhmj59\nepeF1cGDBzV69Gg9/PDDXfL44aIjh/VsOJxrk4qKCiUkJOimm24irELADAsAYAVmWAAAKxBYAAAr\nEFgAACsQWAAAKxBYAAArEFgAACv8P5ZWvQDqsWNNAAAAAElFTkSuQmCC\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0xaeb47b6c>"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "c7a"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 10,
+       "text": [
+        "'WWPA, AWHCRH MDY IOT NJHGK HJWLSBALH HI AWL BBHLJT, X DTUI PC VC MGPSHN HCK AHXK AVL BCAXS PMILG JAVHPCN IPBL. PZ ESPUCLS AWL RYPAT DPZ SLAPKLGLS AD AWLXY NHGK DU UYXKPF PMILGUDVC, ADV AHIL UVG HCFDUT AD WGVRLHZ XA, PUS AWL QVPYS DPZ THHF IV SLIHRO UYDT IOT IPZT. LMJTSALCA XKTH IV BHZL IOT WPPCAXUV SDVZ SXRT WPYI VU AWL QVM IN AWL LHN - UD-VCL LHH NDPCN IV IBGU XA DCTY IV AVDR XM IOTF SPSU\u2019I RCVL PI DPZ IOTYT, HCK IOTF LLGL EYTAIF JUAPZLAF IV QL AVDRXUV MDY HVBLDUT AD ZBBVNAL P WPPCAXUV PC HCFLHN. \\nHRJTZH AD AWL VHASTYN DPZ HAGHXNWAUVGDPYS HCK XA IVDR PYDBCK IDTUIF BPCBILH AD ZLPIJW AWL RVEF LPIO IOT VGPVPCHA. P WPS AWL EHXUIPCN PTDUV H QBCJW VU YTWGVSBRAXVCZ XU IOT TJZTBB ZWVE HCK RHBWTK DBI MDY IOT UXNWA XU IOT NJHGKH\u2019 IPAWYDVB. AJYCZ DBI AWLN WGLULG AD BHL IOT KXYTJIVGZ\u2019 UHRPAPIPTZ JW DU IOT ADW USDVG. DXAW AWL CLL LMOXIXAXVC VELCPCN DU HHIBGKPF IOT WAHRL LHH IJZN LCVJNW AD ZAPE VJA UPGZI AWPCN PUS, HH HGYPUVLS, P BHSL HBGL X DPZ UPGZI PCAD AWL HODW. X UDD WHKL IOT ODUDBG VU OPCXUV IDBVOI AWL ROTHELHA TCTY LVGR QF SH KPCJX. VG UDA. \\nIOT E-GHN YTZJSIZ RHBL QHRR IOXZ BVGUXUV HCK, PZ NVJ ZJZELRATK, IOXZ XZ DUT VU ZPYP\u2019Z UHZLH. P PT IVAK XA XZ RSDZT AD WTYULRA, QBI, OXKSLC BCKTY IOT SPFTYH VU WPPCA, HOT ZRYXIQSTK P WXJIBGL DM IOT UPGX LPNAL TTQSTT XU ALPK. HOT ZXNCLS PI Z IVD. AWL ILRO VBNZ IOXUZ ZWL BHN OPCT BHLS H QPI VU VAK EPEL APZL P JGHNVC AD KTMPJT AWL QVPYS ITMDYT ZWL HAPYILS DDYZ VC PI. HCFLHN, AWHI STHKLH AWL FBTZIPDU DM LOTYT AWL WLAS IOT YTHA WPPCAXUV TXNWA QL. XA\u2019H OPYS AD ITSXLKL IOPA HOT STMI PI DXAW AWL HZ PUS P RHC\u2019A HLT OTY VVXUV VC AWL GBC DXAW PI ZIBRR JUSLG OTY RVPA. XA\u2019H UDA APZL HOT JDBAK GVAS XA JW. \\nX DDYZLS AWYDBVO HVBL BVGL DM IOT UPGX WPWTYH HCK UVJUS AWPH UDAT. HI STHHA XA ILASH BH DWLGL HOT DTUI. SDVZZ APZL IOT JXWWLG JALGR LHH IPJZ IN AWL LHN. P WHKL BVKLS VC AD CTUXJT AD AGF IV UPCK PUN AGHRL DM HHGH IOTYT, IJA X OPCT H ULTSXUV AWL HVABIPDU IV IOXZ BFHATYN PH IPJZ PC WPYXZ LOTYT PI HAS QLVHC. P ALUA IOT WPPCAXUV HI AWL EHGPH VUMXJT. TPFQL NVJ JDBAK PYGHCNT AD YTAJYC PI? PI ZWVJSS IT LPZXLG AD NTA XA XU IOPU XA LHH AD LMAGHRA XA. \\nPSA AWL QLHA, \\nWHGYN\\n'"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vigenere_frequency_break(sanitise(c7a))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 12,
+       "text": [
+        "('hp', 0.03214089578198264)"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "' '.join(segment(vigenere_decipher(sanitise(c7a), 'hp')))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 15,
+       "text": [
+        "'phil thanks for the guard schedules at the museum i went in on friday and laid low until after closing time as planned the crate was delivered to their yard on friday afternoon too late for anyone to process it and the board was easy to detach from the base excellent idea to make the painting look like part of the box by the way no one was going to turn it over to look if they didnt know it was there and they were pretty unlikely to be looking for someone to smuggle a painting in anyway access to the gallery was straightforward and it took around twenty minutes to switch the copy with the original i hid the painting among a bunch of reproductions in the museum shop and camped out for the night in the guards bathroom turns out they prefer to use the directors facilities upon the top floor with the new exhibition opening on saturday the place was busy enough to slip out first thing and as arranged i made sure i was first into the shop i now have the honour of having bought the cheapest ever work by davinci or not the xray results came back this morning and as you suspected this is one of saras fake siam told it is close to perfect but hidden under the layers of paint she scribbled a picture of the nazi eagle emblem in leads he signed its too the tech guys think she may have used abit of old pipe like a crayon to deface the board before she started work on it anyway that leaves the question of where the hell the real painting might be its hard to believe that she left it with the ss and icant see her going on the run with it stuck under her coat its not like she could roll it up i worked through some more of the nazi papers and found this note atleast it tells us where she went looks like the cipher clerk was back by the way i have moved on to venice to try to find any trace of sara there but i have a feeling the solution to this mystery is back in paris where it all began i left the painting at the paris office maybe you could arrange to return it it should be easier to get it in than it was to extract it all the best harry'"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "vigenere_frequency_break(sanitise(c7b))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 16,
+       "text": [
+        "('aattuualptaaauaaaa', 0.10312795085805967)"
+       ]
+      }
+     ],
+     "prompt_number": 16
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "' '.join(segment(vigenere_decipher(sanitise(c7b),'aattuualptaaauaaaa' )))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 17,
+       "text": [
+        "'ttmaqoehqveytelettkf vfantitlnhhttprnmews qrfwquefetnntmmohpun kit a murvsoegeomjsemwelpo yotkcoytmamvgijtrhtk pcrnydlmautreryrciti man rtxrnmzeatctythrycyb obmmisfdefehefyfnvws note neetztxkrqcavlennemh tmeemnnfvulnntneyfrt a ohtmohynxzxnzontunrg hubfooznoirdgkiztyqh eodatncnenpgyccwfmai masxprjmmtoktyiheouf jnteemaetxhkyutyaatk ausmmfuccthuyotxmltn tythhtootmnrnusztdsm mkoiyftfhharuianbwha eixyetfoatnboksfiheu ywcrthbfulmrsaetmlpu ymhtryamodjafttteaff ttnwmqtfzwbhntypttmt are dldnrkyhsacctyerfamm tgomtxzumtmtmtanskid jfpoxhothtoaixvidebb ooeryykftffteelratyh qyurtemtvgeutvsfrheo tcmhyalioyuemnefknco trqiitaonfouaywtmmoo that eu uhpyhnzxttontfaaxnsn of lioptnrtovvxzdiepexy not etielahfcariewfhwwh yiwlvmuudehtbbfvvawi ytkbozvrifacjsiwaagb let now oalfdorpballhktfqtku at hvnxwllfmodtqsluhycv lhiyytejglmrzfdemded dweicjqisrnvlmhudewl kb dgcmklhyhkjalxdosdtq in lfs gewambhlohuwejeltww tbjgeudeucklmxatceud same rpfmjtqmorshwzndcgkm zhieuzasrsoekzgbtbqh rktiwgcavlneuqrzhibj leljrlayqybgewqgrkth wlpiyshwfsillxicblls ebwhcyfkrvmhiomkotdo iwmfahyniseiszwfshlt cxrmaotikmnuachvqdov mmatibzhfoadvloawzke nqrcnrgbxrwfdkctsxxa iejzlnerryfidtbwhxbd hluhtfswwnclgdtwwdvk lhazobmargsgwwtopasg men rl on york rodr keewdeelujkdlellythc wexcfrqxagrdiyunehkn ikfruurtslqbdjrcvujp kxghfbldgmistthujsot bids iwcdsiajaqmanpigbcp zoxlurhnlgrtfifiguor gsm mntfcwavanbilwysatnl mvpnafbhzhwxnrzirhra'"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len(sanitise(c7b))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 18,
+       "text": [
+        "1304"
+       ]
+      }
+     ],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": []
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/cipher.py b/cipher.py
new file mode 100644 (file)
index 0000000..c5d542b
--- /dev/null
+++ b/cipher.py
@@ -0,0 +1,499 @@
+import string
+import collections
+import logging
+import math
+from itertools import zip_longest, cycle, chain
+from language_models import *
+
+logger = logging.getLogger(__name__)
+logger.addHandler(logging.FileHandler('cipher.log'))
+logger.setLevel(logging.WARNING)
+#logger.setLevel(logging.INFO)
+#logger.setLevel(logging.DEBUG)
+
+
+modular_division_table = [[0]*26 for _ in range(26)]
+for a in range(26):
+    for b in range(26):
+        c = (a * b) % 26
+        modular_division_table[b][c] = a
+
+
+def every_nth(text, n, fillvalue=''):
+    """Returns n strings, each of which consists of every nth character, 
+    starting with the 0th, 1st, 2nd, ... (n-1)th character
+    
+    >>> every_nth(string.ascii_lowercase, 5)
+    ['afkpuz', 'bglqv', 'chmrw', 'dinsx', 'ejoty']
+    >>> every_nth(string.ascii_lowercase, 1)
+    ['abcdefghijklmnopqrstuvwxyz']
+    >>> every_nth(string.ascii_lowercase, 26) # doctest: +NORMALIZE_WHITESPACE
+    ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
+     'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
+    >>> every_nth(string.ascii_lowercase, 5, fillvalue='!')
+    ['afkpuz', 'bglqv!', 'chmrw!', 'dinsx!', 'ejoty!']
+    """
+    split_text = [text[i:i+n] for i in range(0, len(text), n)]
+    return [''.join(l) for l in zip_longest(*split_text, fillvalue=fillvalue)]
+
+def combine_every_nth(split_text):
+    """Reforms a text split into every_nth strings
+    
+    >>> combine_every_nth(every_nth(string.ascii_lowercase, 5))
+    'abcdefghijklmnopqrstuvwxyz'
+    >>> combine_every_nth(every_nth(string.ascii_lowercase, 1))
+    'abcdefghijklmnopqrstuvwxyz'
+    >>> combine_every_nth(every_nth(string.ascii_lowercase, 26))
+    'abcdefghijklmnopqrstuvwxyz'
+    """
+    return ''.join([''.join(l) 
+                    for l in zip_longest(*split_text, fillvalue='')])
+
+def chunks(text, n, fillvalue=None):
+    """Split a text into chunks of n characters
+
+    >>> chunks('abcdefghi', 3)
+    ['abc', 'def', 'ghi']
+    >>> chunks('abcdefghi', 4)
+    ['abcd', 'efgh', 'i']
+    >>> chunks('abcdefghi', 4, fillvalue='!')
+    ['abcd', 'efgh', 'i!!!']
+    """
+    if fillvalue:
+        padding = fillvalue[0] * (n - len(text) % n)
+    else:
+        padding = ''
+    return [(text+padding)[i:i+n] for i in range(0, len(text), n)]
+
+def transpose(items, transposition):
+    """Moves items around according to the given transposition
+    
+    >>> transpose(['a', 'b', 'c', 'd'], (0,1,2,3))
+    ['a', 'b', 'c', 'd']
+    >>> transpose(['a', 'b', 'c', 'd'], (3,1,2,0))
+    ['d', 'b', 'c', 'a']
+    >>> transpose([10,11,12,13,14,15], (3,2,4,1,5,0))
+    [13, 12, 14, 11, 15, 10]
+    """
+    transposed = [''] * len(transposition)
+    for p, t in enumerate(transposition):
+       transposed[p] = items[t]
+    return transposed
+
+def untranspose(items, transposition):
+    """Undoes a transpose
+    
+    >>> untranspose(['a', 'b', 'c', 'd'], [0,1,2,3])
+    ['a', 'b', 'c', 'd']
+    >>> untranspose(['d', 'b', 'c', 'a'], [3,1,2,0])
+    ['a', 'b', 'c', 'd']
+    >>> untranspose([13, 12, 14, 11, 15, 10], [3,2,4,1,5,0])
+    [10, 11, 12, 13, 14, 15]
+    """
+    transposed = [''] * len(transposition)
+    for p, t in enumerate(transposition):
+       transposed[t] = items[p]
+    return transposed
+
+def deduplicate(text):
+    return list(collections.OrderedDict.fromkeys(text))
+
+
+def caesar_encipher_letter(letter, shift):
+    """Encipher a letter, given a shift amount
+
+    >>> caesar_encipher_letter('a', 1)
+    'b'
+    >>> caesar_encipher_letter('a', 2)
+    'c'
+    >>> caesar_encipher_letter('b', 2)
+    'd'
+    >>> caesar_encipher_letter('x', 2)
+    'z'
+    >>> caesar_encipher_letter('y', 2)
+    'a'
+    >>> caesar_encipher_letter('z', 2)
+    'b'
+    >>> caesar_encipher_letter('z', -1)
+    'y'
+    >>> caesar_encipher_letter('a', -1)
+    'z'
+    """
+    if letter in string.ascii_letters:
+        if letter in string.ascii_uppercase:
+            alphabet_start = ord('A')
+        else:
+            alphabet_start = ord('a')
+        return chr(((ord(letter) - alphabet_start + shift) % 26) + 
+                   alphabet_start)
+    else:
+        return letter
+
+def caesar_decipher_letter(letter, shift):
+    """Decipher a letter, given a shift amount
+    
+    >>> caesar_decipher_letter('b', 1)
+    'a'
+    >>> caesar_decipher_letter('b', 2)
+    'z'
+    """
+    return caesar_encipher_letter(letter, -shift)
+
+def caesar_encipher(message, shift):
+    """Encipher a message with the Caesar cipher of given shift
+    
+    >>> caesar_encipher('abc', 1)
+    'bcd'
+    >>> caesar_encipher('abc', 2)
+    'cde'
+    >>> caesar_encipher('abcxyz', 2)
+    'cdezab'
+    >>> caesar_encipher('ab cx yz', 2)
+    'cd ez ab'
+    """
+    enciphered = [caesar_encipher_letter(l, shift) for l in message]
+    return ''.join(enciphered)
+
+def caesar_decipher(message, shift):
+    """Encipher a message with the Caesar cipher of given shift
+    
+    >>> caesar_decipher('bcd', 1)
+    'abc'
+    >>> caesar_decipher('cde', 2)
+    'abc'
+    >>> caesar_decipher('cd ez ab', 2)
+    'ab cx yz'
+    """
+    return caesar_encipher(message, -shift)
+
+def affine_encipher_letter(letter, multiplier=1, adder=0, one_based=True):
+    """Encipher a letter, given a multiplier and adder
+    
+    >>> ''.join([affine_encipher_letter(l, 3, 5, True) \
+            for l in string.ascii_uppercase])
+    'HKNQTWZCFILORUXADGJMPSVYBE'
+    >>> ''.join([affine_encipher_letter(l, 3, 5, False) \
+            for l in string.ascii_uppercase])
+    'FILORUXADGJMPSVYBEHKNQTWZC'
+    """
+    if letter in string.ascii_letters:
+        if letter in string.ascii_uppercase:
+            alphabet_start = ord('A')
+        else:
+            alphabet_start = ord('a')
+        letter_number = ord(letter) - alphabet_start
+        if one_based: letter_number += 1
+        cipher_number = (letter_number * multiplier + adder) % 26
+        if one_based: cipher_number -= 1
+        return chr(cipher_number % 26 + alphabet_start)
+    else:
+        return letter
+
+def affine_decipher_letter(letter, multiplier=1, adder=0, one_based=True):
+    """Encipher a letter, given a multiplier and adder
+    
+    >>> ''.join([affine_decipher_letter(l, 3, 5, True) \
+            for l in 'HKNQTWZCFILORUXADGJMPSVYBE'])
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+    >>> ''.join([affine_decipher_letter(l, 3, 5, False) \
+            for l in 'FILORUXADGJMPSVYBEHKNQTWZC'])
+    'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+    """
+    if letter in string.ascii_letters:
+        if letter in string.ascii_uppercase:
+            alphabet_start = ord('A')
+        else:
+            alphabet_start = ord('a')
+        cipher_number = ord(letter) - alphabet_start
+        if one_based: cipher_number += 1
+        plaintext_number = ( 
+            modular_division_table[multiplier]
+                                  [(cipher_number - adder) % 26] )
+        if one_based: plaintext_number -= 1
+        return chr(plaintext_number % 26 + alphabet_start) 
+    else:
+        return letter
+
+def affine_encipher(message, multiplier=1, adder=0, one_based=True):
+    """Encipher a message
+    
+    >>> affine_encipher('hours passed during which jerico tried every ' \
+           'trick he could think of', 15, 22, True)
+    'lmyfu bkuusd dyfaxw claol psfaom jfasd snsfg jfaoe ls omytd jlaxe mh'
+    """
+    enciphered = [affine_encipher_letter(l, multiplier, adder, one_based) 
+                  for l in message]
+    return ''.join(enciphered)
+
+def affine_decipher(message, multiplier=1, adder=0, one_based=True):
+    """Decipher a message
+    
+    >>> affine_decipher('lmyfu bkuusd dyfaxw claol psfaom jfasd snsfg ' \
+           'jfaoe ls omytd jlaxe mh', 15, 22, True)
+    'hours passed during which jerico tried every trick he could think of'
+    """
+    enciphered = [affine_decipher_letter(l, multiplier, adder, one_based) 
+                  for l in message]
+    return ''.join(enciphered)
+
+
+def keyword_cipher_alphabet_of(keyword, wrap_alphabet=0):
+    """Find the cipher alphabet given a keyword.
+    wrap_alphabet controls how the rest of the alphabet is added
+    after the keyword.
+    0 : from 'a'
+    1 : from the last letter in the sanitised keyword
+    2 : from the largest letter in the sanitised keyword
+
+    >>> keyword_cipher_alphabet_of('bayes')
+    'bayescdfghijklmnopqrtuvwxz'
+    >>> keyword_cipher_alphabet_of('bayes', 0)
+    'bayescdfghijklmnopqrtuvwxz'
+    >>> keyword_cipher_alphabet_of('bayes', 1)
+    'bayestuvwxzcdfghijklmnopqr'
+    >>> keyword_cipher_alphabet_of('bayes', 2)
+    'bayeszcdfghijklmnopqrtuvwx'
+    """
+    if wrap_alphabet == 0:
+        cipher_alphabet = ''.join(deduplicate(sanitise(keyword) + 
+                                              string.ascii_lowercase))
+    else:
+        if wrap_alphabet == 1:
+            last_keyword_letter = deduplicate(sanitise(keyword))[-1]
+        else:
+            last_keyword_letter = sorted(sanitise(keyword))[-1]
+        last_keyword_position = string.ascii_lowercase.find(
+            last_keyword_letter) + 1
+        cipher_alphabet = ''.join(
+            deduplicate(sanitise(keyword) + 
+                        string.ascii_lowercase[last_keyword_position:] + 
+                        string.ascii_lowercase))
+    return cipher_alphabet
+
+
+def keyword_encipher(message, keyword, wrap_alphabet=0):
+    """Enciphers a message with a keyword substitution cipher.
+    wrap_alphabet controls how the rest of the alphabet is added
+    after the keyword.
+    0 : from 'a'
+    1 : from the last letter in the sanitised keyword
+    2 : from the largest letter in the sanitised keyword
+
+    >>> keyword_encipher('test message', 'bayes')
+    'rsqr ksqqbds'
+    >>> keyword_encipher('test message', 'bayes', 0)
+    'rsqr ksqqbds'
+    >>> keyword_encipher('test message', 'bayes', 1)
+    'lskl dskkbus'
+    >>> keyword_encipher('test message', 'bayes', 2)
+    'qspq jsppbcs'
+    """
+    cipher_alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet)
+    cipher_translation = ''.maketrans(string.ascii_lowercase, cipher_alphabet)
+    return message.lower().translate(cipher_translation)
+
+def keyword_decipher(message, keyword, wrap_alphabet=0):
+    """Deciphers a message with a keyword substitution cipher.
+    wrap_alphabet controls how the rest of the alphabet is added
+    after the keyword.
+    0 : from 'a'
+    1 : from the last letter in the sanitised keyword
+    2 : from the largest letter in the sanitised keyword
+    
+    >>> keyword_decipher('rsqr ksqqbds', 'bayes')
+    'test message'
+    >>> keyword_decipher('rsqr ksqqbds', 'bayes', 0)
+    'test message'
+    >>> keyword_decipher('lskl dskkbus', 'bayes', 1)
+    'test message'
+    >>> keyword_decipher('qspq jsppbcs', 'bayes', 2)                                                                                            
+    'test message'
+    """
+    cipher_alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet)
+    cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)
+    return message.lower().translate(cipher_translation)
+
+
+def vigenere_encipher(message, keyword):
+    """Vigenere encipher
+
+    >>> vigenere_encipher('hello', 'abc')
+    'hfnlp'
+    """
+    shifts = [ord(l) - ord('a') for l in sanitise(keyword)]
+    pairs = zip(message, cycle(shifts))
+    return ''.join([caesar_encipher_letter(l, k) for l, k in pairs])
+
+def vigenere_decipher(message, keyword):
+    """Vigenere decipher
+
+    >>> vigenere_decipher('hfnlp', 'abc')
+    'hello'
+    """
+    shifts = [ord(l) - ord('a') for l in sanitise(keyword)]
+    pairs = zip(message, cycle(shifts))
+    return ''.join([caesar_decipher_letter(l, k) for l, k in pairs])
+
+beaufort_encipher=vigenere_decipher
+beaufort_decipher=vigenere_encipher
+
+
+def transpositions_of(keyword):
+    """Finds the transpostions given by a keyword. For instance, the keyword
+    'clever' rearranges to 'celrv', so the first column (0) stays first, the
+    second column (1) moves to third, the third column (2) moves to second, 
+    and so on.
+
+    If passed a tuple, assume it's already a transposition and just return it.
+
+    >>> transpositions_of('clever')
+    (0, 2, 1, 4, 3)
+    >>> transpositions_of('fred')
+    (3, 2, 0, 1)
+    >>> transpositions_of((3, 2, 0, 1))
+    (3, 2, 0, 1)
+    """
+    if isinstance(keyword, tuple):
+        return keyword
+    else:
+        key = deduplicate(keyword)
+        transpositions = tuple(key.index(l) for l in sorted(key))
+        return transpositions
+
+def pad(message_len, group_len, fillvalue):
+    padding_length = group_len - message_len % group_len
+    if padding_length == group_len: padding_length = 0
+    padding = ''
+    for i in range(padding_length):
+        if callable(fillvalue):
+            padding += fillvalue()
+        else:
+            padding += fillvalue
+    return padding
+
+def column_transposition_encipher(message, keyword, fillvalue=' ', 
+      fillcolumnwise=False,
+      emptycolumnwise=False):
+    """Enciphers using the column transposition cipher.
+    Message is padded to allow all rows to be the same length.
+
+    >>> column_transposition_encipher('hellothere', 'abcdef', fillcolumnwise=True)
+    'hlohr eltee '
+    >>> column_transposition_encipher('hellothere', 'abcdef', fillcolumnwise=True, emptycolumnwise=True)
+    'hellothere  '
+    >>> column_transposition_encipher('hellothere', 'abcdef')
+    'hellothere  '
+    >>> column_transposition_encipher('hellothere', 'abcde')
+    'hellothere'
+    >>> column_transposition_encipher('hellothere', 'abcde', fillcolumnwise=True, emptycolumnwise=True)
+    'hellothere'
+    >>> column_transposition_encipher('hellothere', 'abcde', fillcolumnwise=True, emptycolumnwise=False)
+    'hlohreltee'
+    >>> column_transposition_encipher('hellothere', 'abcde', fillcolumnwise=False, emptycolumnwise=True)
+    'htehlelroe'
+    >>> column_transposition_encipher('hellothere', 'abcde', fillcolumnwise=False, emptycolumnwise=False)
+    'hellothere'
+    >>> column_transposition_encipher('hellothere', 'clever', fillcolumnwise=True, emptycolumnwise=True)
+    'heotllrehe'
+    >>> column_transposition_encipher('hellothere', 'clever', fillcolumnwise=True, emptycolumnwise=False)
+    'holrhetlee'
+    >>> column_transposition_encipher('hellothere', 'clever', fillcolumnwise=False, emptycolumnwise=True)
+    'htleehoelr'
+    >>> column_transposition_encipher('hellothere', 'clever', fillcolumnwise=False, emptycolumnwise=False)
+    'hleolteher'
+    >>> column_transposition_encipher('hellothere', 'cleverly')
+    'hleolthre e '
+    >>> column_transposition_encipher('hellothere', 'cleverly', fillvalue='!')
+    'hleolthre!e!'
+    >>> column_transposition_encipher('hellothere', 'cleverly', fillvalue=lambda: '*')
+    'hleolthre*e*'
+    """
+    transpositions = transpositions_of(keyword)
+    message += pad(len(message), len(transpositions), fillvalue)
+    if fillcolumnwise:
+        rows = every_nth(message, len(message) // len(transpositions))
+    else:
+        rows = chunks(message, len(transpositions))
+    transposed = [transpose(r, transpositions) for r in rows]
+    if emptycolumnwise:
+        return combine_every_nth(transposed)
+    else:
+        return ''.join(chain(*transposed))
+
+def column_transposition_decipher(message, keyword, fillvalue=' ', 
+      fillcolumnwise=False,
+      emptycolumnwise=False):
+    """Deciphers using the column transposition cipher.
+    Message is padded to allow all rows to be the same length.
+
+    >>> column_transposition_decipher('hellothere', 'abcde', fillcolumnwise=True, emptycolumnwise=True)
+    'hellothere'
+    >>> column_transposition_decipher('hlohreltee', 'abcde', fillcolumnwise=True, emptycolumnwise=False)
+    'hellothere'
+    >>> column_transposition_decipher('htehlelroe', 'abcde', fillcolumnwise=False, emptycolumnwise=True)
+    'hellothere'
+    >>> column_transposition_decipher('hellothere', 'abcde', fillcolumnwise=False, emptycolumnwise=False)
+    'hellothere'
+    >>> column_transposition_decipher('heotllrehe', 'clever', fillcolumnwise=True, emptycolumnwise=True)
+    'hellothere'
+    >>> column_transposition_decipher('holrhetlee', 'clever', fillcolumnwise=True, emptycolumnwise=False)
+    'hellothere'
+    >>> column_transposition_decipher('htleehoelr', 'clever', fillcolumnwise=False, emptycolumnwise=True)
+    'hellothere'
+    >>> column_transposition_decipher('hleolteher', 'clever', fillcolumnwise=False, emptycolumnwise=False)
+    'hellothere'
+    """
+    transpositions = transpositions_of(keyword)
+    message += pad(len(message), len(transpositions), '*')
+    if emptycolumnwise:
+        rows = every_nth(message, len(message) // len(transpositions))
+    else:
+        rows = chunks(message, len(transpositions))
+    untransposed = [untranspose(r, transpositions) for r in rows]
+    if fillcolumnwise:
+        return combine_every_nth(untransposed)
+    else:
+        return ''.join(chain(*untransposed))
+
+def scytale_encipher(message, rows, fillvalue=' '):
+    """Enciphers using the scytale transposition cipher.
+    Message is padded with spaces to allow all rows to be the same length.
+
+    >>> scytale_encipher('thequickbrownfox', 3)
+    'tcnhkfeboqrxuo iw '
+    >>> scytale_encipher('thequickbrownfox', 4)
+    'tubnhirfecooqkwx'
+    >>> scytale_encipher('thequickbrownfox', 5)
+    'tubnhirfecooqkwx'
+    >>> scytale_encipher('thequickbrownfox', 6)
+    'tqcrnxhukof eibwo '
+    >>> scytale_encipher('thequickbrownfox', 7)
+    'tqcrnxhukof eibwo '
+    """
+    transpositions = [i for i in range(math.ceil(len(message) / rows))]
+    return column_transposition_encipher(message, transpositions, 
+        fillcolumnwise=False, emptycolumnwise=True)
+
+def scytale_decipher(message, rows):
+    """Deciphers using the scytale transposition cipher.
+    Assumes the message is padded so that all rows are the same length.
+    
+    >>> scytale_decipher('tcnhkfeboqrxuo iw ', 3)
+    'thequickbrownfox  '
+    >>> scytale_decipher('tubnhirfecooqkwx', 4)
+    'thequickbrownfox'
+    >>> scytale_decipher('tubnhirfecooqkwx', 5)
+    'thequickbrownfox'
+    >>> scytale_decipher('tqcrnxhukof eibwo ', 6)
+    'thequickbrownfox  '
+    >>> scytale_decipher('tqcrnxhukof eibwo ', 7)
+    'thequickbrownfox  '
+    """
+    transpositions = [i for i in range(math.ceil(len(message) / rows))]
+    return column_transposition_decipher(message, transpositions, 
+        fillcolumnwise=False, emptycolumnwise=True)
+
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
diff --git a/cipher.sublime-project b/cipher.sublime-project
new file mode 100644 (file)
index 0000000..2c63c08
--- /dev/null
@@ -0,0 +1,2 @@
+{
+}
diff --git a/cipherbreak.py b/cipherbreak.py
new file mode 100644 (file)
index 0000000..d2c35c9
--- /dev/null
@@ -0,0 +1,416 @@
+import string
+import collections
+import norms
+import logging
+from itertools import zip_longest, cycle, permutations
+from segment import segment
+from multiprocessing import Pool
+from math import log10
+
+import matplotlib.pyplot as plt
+
+from cipher import *
+from language_models import *
+
+# To time a run:
+#
+# import timeit
+# c5a = open('2012/5a.ciphertext', 'r').read()
+# timeit.timeit('keyword_break(c5a)', setup='gc.enable() ; from __main__ import c5a ; from cipher import keyword_break', number=1)
+# timeit.repeat('keyword_break_mp(c5a, chunksize=500)', setup='gc.enable() ; from __main__ import c5a ; from cipher import keyword_break_mp', repeat=5, number=1)
+
+transpositions = collections.defaultdict(list)
+for word in keywords:
+    transpositions[transpositions_of(word)] += [word]
+
+def frequencies(text):
+    """Count the number of occurrences of each character in text
+    
+    >>> sorted(frequencies('abcdefabc').items())
+    [('a', 2), ('b', 2), ('c', 2), ('d', 1), ('e', 1), ('f', 1)]
+    >>> sorted(frequencies('the quick brown fox jumped over the lazy ' \
+         'dog').items()) # doctest: +NORMALIZE_WHITESPACE
+    [(' ', 8), ('a', 1), ('b', 1), ('c', 1), ('d', 2), ('e', 4), ('f', 1), 
+     ('g', 1), ('h', 2), ('i', 1), ('j', 1), ('k', 1), ('l', 1), ('m', 1), 
+     ('n', 1), ('o', 4), ('p', 1), ('q', 1), ('r', 2), ('t', 2), ('u', 2), 
+     ('v', 1), ('w', 1), ('x', 1), ('y', 1), ('z', 1)]
+    >>> sorted(frequencies('The Quick BROWN fox jumped! over... the ' \
+         '(9lazy) DOG').items()) # doctest: +NORMALIZE_WHITESPACE
+    [(' ', 8), ('!', 1), ('(', 1), (')', 1), ('.', 3), ('9', 1), ('B', 1), 
+     ('D', 1), ('G', 1), ('N', 1), ('O', 2), ('Q', 1), ('R', 1), ('T', 1), 
+     ('W', 1), ('a', 1), ('c', 1), ('d', 1), ('e', 4), ('f', 1), ('h', 2), 
+     ('i', 1), ('j', 1), ('k', 1), ('l', 1), ('m', 1), ('o', 2), ('p', 1), 
+     ('r', 1), ('t', 1), ('u', 2), ('v', 1), ('x', 1), ('y', 1), ('z', 1)]
+    >>> sorted(frequencies(sanitise('The Quick BROWN fox jumped! over... ' \
+         'the (9lazy) DOG')).items()) # doctest: +NORMALIZE_WHITESPACE
+    [('a', 1), ('b', 1), ('c', 1), ('d', 2), ('e', 4), ('f', 1), ('g', 1), 
+     ('h', 2), ('i', 1), ('j', 1), ('k', 1), ('l', 1), ('m', 1), ('n', 1), 
+     ('o', 4), ('p', 1), ('q', 1), ('r', 2), ('t', 2), ('u', 2), ('v', 1), 
+     ('w', 1), ('x', 1), ('y', 1), ('z', 1)]
+    >>> frequencies('abcdefabcdef')['x']
+    0
+    """
+    #counts = collections.defaultdict(int)
+    #for c in text: 
+    #    counts[c] += 1
+    #return counts
+    return collections.Counter(c for c in text)
+
+
+def caesar_break(message, fitness=Pletters):
+    """Breaks a Caesar cipher using frequency analysis
+    
+    >>> caesar_break('ibxcsyorsaqcheyklxivoexlevmrimwxsfiqevvmihrsasrxliwyrh' \
+          'ecjsppsamrkwleppfmergefifvmhixscsymjcsyqeoixlm') # doctest: +ELLIPSIS
+    (4, -130.849890899...)
+    >>> caesar_break('wxwmaxdgheetgwuxztgptedbgznitgwwhpguxyhkxbmhvvtlbhgtee' \
+          'raxlmhiixweblmxgxwmhmaxybkbgztgwztsxwbgmxgmert') # doctest: +ELLIPSIS
+    (19, -128.82516920...)
+    >>> caesar_break('yltbbqnqnzvguvaxurorgenafsbezqvagbnornfgsbevpnaabjurer' \
+          'svaquvzyvxrnznazlybequrvfohgriraabjtbaruraprur') # doctest: +ELLIPSIS
+    (13, -126.25233502...)
+    """
+    sanitised_message = sanitise(message)
+    best_shift = 0
+    best_fit = float('-inf')
+    for shift in range(26):
+        plaintext = caesar_decipher(sanitised_message, shift)
+        fit = fitness(plaintext)
+        logger.debug('Caesar break attempt using key {0} gives fit of {1} '
+                      'and decrypt starting: {2}'.format(shift, fit, plaintext[:50]))
+        if fit > best_fit:
+            best_fit = fit
+            best_shift = shift
+    logger.info('Caesar break best fit: key {0} gives fit of {1} and '
+                'decrypt starting: {2}'.format(best_shift, best_fit, 
+                    caesar_decipher(sanitised_message, best_shift)[:50]))
+    return best_shift, best_fit
+
+def affine_break(message, fitness=Pletters):
+    """Breaks an affine cipher using frequency analysis
+    
+    >>> affine_break('lmyfu bkuusd dyfaxw claol psfaom jfasd snsfg jfaoe ls ' \
+          'omytd jlaxe mh jm bfmibj umis hfsul axubafkjamx. ls kffkxwsd jls ' \
+          'ofgbjmwfkiu olfmxmtmwaokttg jlsx ls kffkxwsd jlsi zg tsxwjl. jlsx ' \
+          'ls umfjsd jlsi zg hfsqysxog. ls dmmdtsd mx jls bats mh bkbsf. ls ' \
+          'bfmctsd kfmyxd jls lyj, mztanamyu xmc jm clm cku tmmeaxw kj lai ' \
+          'kxd clm ckuxj.') # doctest: +ELLIPSIS
+    ((15, 22, True), -340.611412245...)
+    """
+    sanitised_message = sanitise(message)
+    best_multiplier = 0
+    best_adder = 0
+    best_one_based = True
+    best_fit = float("-inf")
+    for one_based in [True, False]:
+        for multiplier in [x for x in range(1, 26, 2) if x != 13]:
+            for adder in range(26):
+                plaintext = affine_decipher(sanitised_message, 
+                                            multiplier, adder, one_based)
+                fit = fitness(plaintext)
+                logger.debug('Affine break attempt using key {0}x+{1} ({2}) '
+                             'gives fit of {3} and decrypt starting: {4}'.
+                             format(multiplier, adder, one_based, fit, 
+                                    plaintext[:50]))
+                if fit > best_fit:
+                    best_fit = fit
+                    best_multiplier = multiplier
+                    best_adder = adder
+                    best_one_based = one_based
+    logger.info('Affine break best fit with key {0}x+{1} ({2}) gives fit of {3} '
+                'and decrypt starting: {4}'.format(
+                    best_multiplier, best_adder, best_one_based, best_fit, 
+                    affine_decipher(sanitised_message, best_multiplier, 
+                        best_adder, best_one_based)[:50]))
+    return (best_multiplier, best_adder, best_one_based), best_fit
+
+def keyword_break(message, wordlist=keywords, fitness=Pletters):
+    """Breaks a keyword substitution cipher using a dictionary and 
+    frequency analysis
+
+    >>> keyword_break(keyword_encipher('this is a test message for the ' \
+          'keyword decipherment', 'elephant', 1), \
+          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
+    (('elephant', 1), -52.8345642265...)
+    """
+    best_keyword = ''
+    best_wrap_alphabet = True
+    best_fit = float("-inf")
+    for wrap_alphabet in range(3):
+        for keyword in wordlist:
+            plaintext = keyword_decipher(message, keyword, wrap_alphabet)
+            fit = fitness(plaintext)
+            logger.debug('Keyword break attempt using key {0} (wrap={1}) '
+                         'gives fit of {2} and decrypt starting: {3}'.format(
+                             keyword, wrap_alphabet, fit, 
+                             sanitise(plaintext)[:50]))
+            if fit > best_fit:
+                best_fit = fit
+                best_keyword = keyword
+                best_wrap_alphabet = wrap_alphabet
+    logger.info('Keyword break best fit with key {0} (wrap={1}) gives fit of '
+                '{2} and decrypt starting: {3}'.format(best_keyword, 
+                    best_wrap_alphabet, best_fit, sanitise(
+                        keyword_decipher(message, best_keyword, 
+                                         best_wrap_alphabet))[:50]))
+    return (best_keyword, best_wrap_alphabet), best_fit
+
+def keyword_break_mp(message, wordlist=keywords, fitness=Pletters, chunksize=500):
+    """Breaks a keyword substitution cipher using a dictionary and 
+    frequency analysis
+
+    >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \
+          'keyword decipherment', 'elephant', 1), \
+          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
+    (('elephant', 1), -52.834564226507...)
+    """
+    with Pool() as pool:
+        helper_args = [(message, word, wrap, fitness) 
+                       for word in wordlist for wrap in range(3)]
+        # Gotcha: the helper function here needs to be defined at the top level 
+        #   (limitation of Pool.starmap)
+        breaks = pool.starmap(keyword_break_worker, helper_args, chunksize) 
+        return max(breaks, key=lambda k: k[1])
+
+def keyword_break_worker(message, keyword, wrap_alphabet, fitness):
+    plaintext = keyword_decipher(message, keyword, wrap_alphabet)
+    fit = fitness(plaintext)
+    logger.debug('Keyword break attempt using key {0} (wrap={1}) gives fit of '
+                 '{2} and decrypt starting: {3}'.format(keyword, 
+                     wrap_alphabet, fit, sanitise(plaintext)[:50]))
+    return (keyword, wrap_alphabet), fit
+
+def scytale_break(message, fitness=Pbigrams):
+    """Breaks a Scytale cipher
+    
+    >>> scytale_break('tfeulchtrtteehwahsdehneoifeayfsondmwpltmaoalhikotoere' \
+           'dcweatehiplwxsnhooacgorrcrcraotohsgullasenylrendaianeplscdriioto' \
+           'aek') # doctest: +ELLIPSIS
+    (6, -281.276219108...)
+    """
+    best_key = 0
+    best_fit = float("-inf")
+    for key in range(1, 20):
+        if len(message) % key == 0:
+            plaintext = scytale_decipher(message, key)
+            fit = fitness(sanitise(plaintext))
+            logger.debug('Scytale break attempt using key {0} gives fit of '
+                         '{1} and decrypt starting: {2}'.format(key, 
+                             fit, sanitise(plaintext)[:50]))
+            if fit > best_fit:
+                best_fit = fit
+                best_key = key
+    logger.info('Scytale break best fit with key {0} gives fit of {1} and '
+                'decrypt starting: {2}'.format(best_key, best_fit, 
+                    sanitise(scytale_decipher(message, best_key))[:50]))
+    return best_key, best_fit
+
+
+def column_transposition_break_mp(message, translist=transpositions, 
+                     fitness=Pbigrams, chunksize=500):
+    """Breaks a column transposition cipher using a dictionary and 
+    n-gram frequency analysis
+    """
+    # >>> column_transposition_break_mp(column_transposition_encipher(sanitise( \
+    #         "It is a truth universally acknowledged, that a single man in \
+    #          possession of a good fortune, must be in want of a wife. However \
+    #          little known the feelings or views of such a man may be on his \
+    #          first entering a neighbourhood, this truth is so well fixed in the \
+    #          minds of the surrounding families, that he is considered the \
+    #          rightful property of some one or other of their daughters."), \
+    #     'encipher'), \
+    #     translist={(2, 0, 5, 3, 1, 4, 6): ['encipher'], \
+    #                (5, 0, 6, 1, 3, 4, 2): ['fourteen'], \
+    #                (6, 1, 0, 4, 5, 3, 2): ['keyword']}) # doctest: +ELLIPSIS
+    # (((2, 0, 5, 3, 1, 4, 6), False), 0.0628106372...)
+    # >>> column_transposition_break_mp(column_transposition_encipher(sanitise( \
+    #         "It is a truth universally acknowledged, that a single man in \
+    #          possession of a good fortune, must be in want of a wife. However \
+    #          little known the feelings or views of such a man may be on his \
+    #          first entering a neighbourhood, this truth is so well fixed in the \
+    #          minds of the surrounding families, that he is considered the \
+    #          rightful property of some one or other of their daughters."), \
+    #     'encipher'), \
+    #     translist={(2, 0, 5, 3, 1, 4, 6): ['encipher'], \
+    #                (5, 0, 6, 1, 3, 4, 2): ['fourteen'], \
+    #                (6, 1, 0, 4, 5, 3, 2): ['keyword']}, \
+    #     target_counts=normalised_english_trigram_counts) # doctest: +ELLIPSIS
+    # (((2, 0, 5, 3, 1, 4, 6), False), 0.0592259560...)
+    # """
+    with Pool() as pool:
+        helper_args = [(message, trans, columnwise, fitness) 
+                       for trans in translist.keys() 
+                       for columnwise in [True, False]]
+        # Gotcha: the helper function here needs to be defined at the top level 
+        #   (limitation of Pool.starmap)
+        breaks = pool.starmap(column_transposition_break_worker, 
+          helper_args, chunksize) 
+        return max(breaks, key=lambda k: k[1])
+column_transposition_break = column_transposition_break_mp
+
+def column_transposition_break_worker(message, transposition, columnwise, 
+                                        fitness):
+    plaintext = column_transposition_decipher(message, transposition, columnwise=columnwise)
+    fit = fitness(sanitise(plaintext))
+    logger.debug('Column transposition break attempt using key {0} '
+                         'gives fit of {1} and decrypt starting: {2}'.format(
+                             transposition, fit, 
+                             sanitise(plaintext)[:50]))
+    return (transposition, columnwise), fit
+
+
+def transposition_break_exhaustive(message, fitness=Pbigrams):
+    best_transposition = ''
+    best_pw = float('-inf')
+    for keylength in range(1, 21):
+        if len(message) % keylength == 0:
+            for transposition in permutations(range(keylength)):
+                for columnwise in [True, False]:
+                    plaintext = column_transposition_decipher(message, 
+                        transposition, columnwise=columnwise)
+                    fit=fitness(plaintext)
+                    logger.debug('Column transposition break attempt using key {0} {1} '
+                         'gives fit of {2} and decrypt starting: {3}'.format(
+                             transposition, columnwise, pw, 
+                             sanitise(plaintext)[:50]))
+                    if fit > best_fit:
+                        best_transposition = transposition
+                        best_columnwise = columnwise
+                        best_fit = fit
+    return (best_transposition, best_columnwise), best_pw
+
+
+def vigenere_keyword_break(message, wordlist=keywords, fitness=Pletters):
+    """Breaks a vigenere cipher using a dictionary and 
+    frequency analysis
+    
+    >>> vigenere_keyword_break(vigenere_encipher(sanitise('this is a test ' \
+             'message for the vigenere decipherment'), 'cat'), \
+             wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
+    ('cat', -52.9479167030...)
+    """
+    best_keyword = ''
+    best_fit = float("-inf")
+    for keyword in wordlist:
+        plaintext = vigenere_decipher(message, keyword)
+        fit = fitness(plaintext)
+        logger.debug('Vigenere break attempt using key {0} '
+                         'gives fit of {1} and decrypt starting: {2}'.format(
+                             keyword, fit, 
+                             sanitise(plaintext)[:50]))
+        if fit > best_fit:
+            best_fit = fit
+            best_keyword = keyword
+    logger.info('Vigenere break best fit with key {0} gives fit '
+                'of {1} and decrypt starting: {2}'.format(best_keyword, 
+                    best_fit, sanitise(
+                        vigenere_decipher(message, best_keyword))[:50]))
+    return best_keyword, best_fit
+
+def vigenere_keyword_break_mp(message, wordlist=keywords, fitness=Pletters, 
+                     chunksize=500):
+    """Breaks a vigenere cipher using a dictionary and 
+    frequency analysis
+
+    >>> vigenere_keyword_break_mp(vigenere_encipher(sanitise('this is a test ' \
+             'message for the vigenere decipherment'), 'cat'), \
+             wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
+    ('cat', -52.9479167030...)
+    """
+    with Pool() as pool:
+        helper_args = [(message, word, fitness) 
+                       for word in wordlist]
+        # Gotcha: the helper function here needs to be defined at the top level 
+        #   (limitation of Pool.starmap)
+        breaks = pool.starmap(vigenere_keyword_break_worker, helper_args, chunksize) 
+        return max(breaks, key=lambda k: k[1])
+
+def vigenere_keyword_break_worker(message, keyword, fitness):
+    plaintext = vigenere_decipher(message, keyword)
+    fit = fitness(plaintext)
+    logger.debug('Vigenere keyword break attempt using key {0} gives fit of '
+                 '{1} and decrypt starting: {2}'.format(keyword, 
+                     fit, sanitise(plaintext)[:50]))
+    return keyword, fit
+
+
+
+def vigenere_frequency_break(message, fitness=Pletters):
+    """Breaks a Vigenere cipher with frequency analysis
+
+    >>> vigenere_frequency_break(vigenere_encipher(sanitise("It is time to " \
+            "run. She is ready and so am I. I stole Daniel's pocketbook this " \
+            "afternoon when he left his jacket hanging on the easel in the " \
+            "attic. I jump every time I hear a footstep on the stairs, " \
+            "certain that the theft has been discovered and that I will " \
+            "be caught. The SS officer visits less often now that he is " \
+            "sure"), 'florence')) # doctest: +ELLIPSIS
+    ('florence', -307.5549865898...)
+    """
+    best_fit = float("-inf")
+    best_key = ''
+    sanitised_message = sanitise(message)
+    for trial_length in range(1, 20):
+        splits = every_nth(sanitised_message, trial_length)
+        key = ''.join([chr(caesar_break(s)[0] + ord('a')) for s in splits])
+        plaintext = vigenere_decipher(sanitised_message, key)
+        fit = fitness(plaintext)
+        logger.debug('Vigenere key length of {0} ({1}) gives fit of {2}'.
+                     format(trial_length, key, fit))
+        if fit > best_fit:
+            best_fit = fit
+            best_key = key
+    logger.info('Vigenere break best fit with key {0} gives fit '
+                'of {1} and decrypt starting: {2}'.format(best_key, 
+                    best_fit, sanitise(
+                        vigenere_decipher(message, best_key))[:50]))
+    return best_key, best_fit
+
+def beaufort_frequency_break(message, fitness=Pletters):
+    """Breaks a Beaufort cipher with frequency analysis
+
+    >>> beaufort_frequency_break(beaufort_encipher(sanitise("It is time to " \
+            "run. She is ready and so am I. I stole Daniel's pocketbook this " \
+            "afternoon when he left his jacket hanging on the easel in the " \
+            "attic. I jump every time I hear a footstep on the stairs, " \
+            "certain that the theft has been discovered and that I will " \
+            "be caught. The SS officer visits less often now " \
+            "that he is sure"), 'florence')) # doctest: +ELLIPSIS
+    ('florence', -307.5549865898...)
+    """
+    best_fit = float("-inf")
+    best_key = ''
+    sanitised_message = sanitise(message)
+    for trial_length in range(1, 20):
+        splits = every_nth(sanitised_message, trial_length)
+        key = ''.join([chr(-caesar_break(s)[0] % 26 + ord('a')) for s in splits])
+        plaintext = beaufort_decipher(sanitised_message, key)
+        fit = fitness(plaintext)
+        logger.debug('Beaufort key length of {0} ({1}) gives fit of {2}'.
+                     format(trial_length, key, fit))
+        if fit > best_fit:
+            best_fit = fit
+            best_key = key
+    logger.info('Beaufort break best fit with key {0} gives fit '
+                'of {1} and decrypt starting: {2}'.format(best_key, 
+                    best_fit, sanitise(
+                        beaufort_decipher(message, best_key))[:50]))
+    return best_key, best_fit
+
+
+
+def plot_frequency_histogram(freqs, sort_key=None):
+    x = range(len(freqs.keys()))
+    y = [freqs[l] for l in sorted(freqs.keys(), key=sort_key)]
+    f = plt.figure()
+    ax = f.add_axes([0.1, 0.1, 0.9, 0.9])
+    ax.bar(x, y, align='center')
+    ax.set_xticks(x)
+    ax.set_xticklabels(sorted(freqs.keys(), key=sort_key))
+    f.show()
+
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
+
diff --git a/find_best_caesar_break_parameters.py b/find_best_caesar_break_parameters.py
new file mode 100644 (file)
index 0000000..9ed5348
--- /dev/null
@@ -0,0 +1,90 @@
+import random
+import collections
+from cipher import *
+from cipherbreak import *
+import itertools
+
+corpus = sanitise(''.join([open('shakespeare.txt', 'r').read(), 
+    open('sherlock-holmes.txt', 'r').read(), 
+    open('war-and-peace.txt', 'r').read()]))
+corpus_length = len(corpus)
+
+euclidean_scaled_english_counts = norms.euclidean_scale(english_counts)
+
+# def frequency_compare(text, target_frequency, frequency_scaling, metric):
+#     counts = frequency_scaling(frequencies(text))
+#     return -1 * metric(target_frequency, counts)
+
+# def euclidean_compare(text):
+#     return frequency_compare(text, norms.euclidean_scale(english_counts),
+#             norms.euclidean_scale, norms.euclidean_distance)
+
+metrics = [{'func': norms.l1, 'invert': True, 'name': 'l1'}, 
+    {'func': norms.l2, 'invert': True, 'name': 'l2'},
+    {'func': norms.l3, 'invert': True, 'name': 'l3'},
+    {'func': norms.cosine_distance, 'invert': False, 'name': 'cosine_distance'},
+    {'func': norms.harmonic_mean, 'invert': True, 'name': 'harmonic_mean'},
+    {'func': norms.geometric_mean, 'invert': True, 'name': 'geometric_mean'}]
+scalings = [{'corpus_frequency': normalised_english_counts, 
+         'scaling': norms.normalise,
+         'name': 'normalised'},
+        {'corpus_frequency': euclidean_scaled_english_counts, 
+         'scaling': norms.euclidean_scale,
+         'name': 'euclidean_scaled'}]
+message_lengths = [300, 100, 50, 30, 20, 10, 5]
+
+trials = 5000
+
+scores = {}
+
+
+def make_frequency_compare_function(target_frequency, frequency_scaling, metric, invert):
+    def frequency_compare(text):
+        counts = frequency_scaling(frequencies(text))
+        if invert:
+            score = -1 * metric(target_frequency, counts)
+        else:
+            score = metric(target_frequency, counts)
+        return score
+    return frequency_compare
+
+
+def scoring_functions():
+    return [{'func': make_frequency_compare_function(s['corpus_frequency'], 
+                s['scaling'], m['func'], m['invert']),
+            'name': '{} + {}'.format(m['name'], s['name'])}
+        for m in metrics
+        for s in scalings] + [{'func': Pletters, 'name': 'Pletters'}]
+
+def eval_scores():
+    [eval_one_score(f, l) 
+        for f in scoring_functions()
+        for l in message_lengths]
+
+def eval_one_score(scoring_function, message_length):
+    print(scoring_function['name'], message_length)
+    if scoring_function['name'] not in scores:
+        scores[scoring_function['name']] = collections.defaultdict(int)
+    for _ in range(trials):
+        sample_start = random.randint(0, corpus_length - message_length)
+        sample = corpus[sample_start:(sample_start + message_length)]
+        key = random.randint(1, 25)
+        ciphertext = caesar_encipher(sample, key)
+        found_key, _ = caesar_break(ciphertext, scoring_function['func'])
+        if found_key == key:
+            scores[scoring_function['name']][message_length] += 1 
+    return scores[scoring_function['name']][message_length]
+
+def show_results():
+    with open('caesar_break_parameter_trials.csv', 'w') as f:
+        print(',message_length', file = f)
+        print('scoring,', ', '.join([str(l) for l in message_lengths]), file = f)
+        for scoring in sorted(scores.keys()):
+            for length in message_lengths:
+                print(scoring, end='', sep='', file=f)
+                for l in message_lengths:
+                    print(',', scores[scoring][l] / trials, end='', file=f)
+                print('', file = f)
+
+eval_scores()
+show_results()
diff --git a/find_wikipedia_titles.py b/find_wikipedia_titles.py
new file mode 100644 (file)
index 0000000..8d56124
--- /dev/null
@@ -0,0 +1,35 @@
+import urllib.request
+import urllib.parse
+import json
+import time
+
+initial_request_url = "http://en.wikipedia.org/w/api.php?action=query&list=allpages&format=json&aplimit=10&apminsize=5000"
+request_url = "http://en.wikipedia.org/w/api.php?action=query&list=allpages&format=json&aplimit=10&apminsize=5000&apcontinue={}"
+titles_file = '/opt/sources/wp-titles.txt'
+
+def titles_of(result):
+    return [p['title'] for p in result['query']['allpages'] ]
+
+def next_title(result):
+    return result['query-continue']['allpages']['apcontinue']
+
+def write_titles(titles):
+    with open(titles_file, 'a') as f:
+        print('\n'.join(titles), file=f)
+
+def request_again(start_title):
+    request = urllib.request.Request(request_url.format(urllib.parse.quote(start_title)))
+    request.add_header('User-Agent','neil.wpspider@njae.me.uk')
+    result = json.loads(urllib.request.urlopen(request).read().decode())
+    return titles_of(result), next_title(result)
+
+f = open(titles_file, 'w')
+f.close()
+
+result = json.loads(urllib.request.urlopen(initial_request_url).read().decode())
+n_title = next_title(result)
+titles = titles_of(result)
+while titles != []:
+    write_titles(titles)
+    time.sleep(0.5)
+    titles, n_title = request_again(n_title)
diff --git a/language_models.py b/language_models.py
new file mode 100644 (file)
index 0000000..9297468
--- /dev/null
@@ -0,0 +1,156 @@
+import string
+import norms
+import random
+import collections
+import unicodedata
+import itertools
+from math import log10
+
+def letters(text):
+    """Remove all non-alphabetic characters from a text
+    >>> letters('The Quick')
+    'TheQuick'
+    >>> letters('The Quick BROWN fox jumped! over... the (9lazy) DOG')
+    'TheQuickBROWNfoxjumpedoverthelazyDOG'
+    """
+    return ''.join([c for c in text if c in string.ascii_letters])
+
+def unaccent(text):
+    """Remove all accents from letters. 
+    It does this by converting the unicode string to decomposed compatability
+    form, dropping all the combining accents, then re-encoding the bytes.
+
+    >>> unaccent('hello')
+    'hello'
+    >>> unaccent('HELLO')
+    'HELLO'
+    >>> unaccent('héllo')
+    'hello'
+    >>> unaccent('héllö')
+    'hello'
+    >>> unaccent('HÉLLÖ')
+    'HELLO'
+    """
+    return unicodedata.normalize('NFKD', text).\
+        encode('ascii', 'ignore').\
+        decode('utf-8')
+
+def sanitise(text):
+    """Remove all non-alphabetic characters and convert the text to lowercase
+    
+    >>> sanitise('The Quick')
+    'thequick'
+    >>> sanitise('The Quick BROWN fox jumped! over... the (9lazy) DOG')
+    'thequickbrownfoxjumpedoverthelazydog'
+    >>> sanitise('HÉLLÖ')
+    'hello'
+    """
+    # sanitised = [c.lower() for c in text if c in string.ascii_letters]
+    # return ''.join(sanitised)
+    return letters(unaccent(text)).lower()
+
+
+def datafile(name, sep='\t'):
+    """Read key,value pairs from file.
+    """
+    with open(name, 'r') as f:
+        for line in f:
+            splits = line.split(sep)
+            yield [splits[0], int(splits[1])]
+
+english_counts = collections.Counter(dict(datafile('count_1l.txt')))
+normalised_english_counts = norms.normalise(english_counts)
+
+english_bigram_counts = collections.Counter(dict(datafile('count_2l.txt')))
+normalised_english_bigram_counts = norms.normalise(english_bigram_counts)
+
+english_trigram_counts = collections.Counter(dict(datafile('count_3l.txt')))
+normalised_english_trigram_counts = norms.normalise(english_trigram_counts)
+
+with open('words.txt', 'r') as f:
+    keywords = [line.rstrip() for line in f]
+
+
+def weighted_choice(d):
+       """Generate random item from a dictionary of item counts
+       """
+       target = random.uniform(0, sum(d.values()))
+       cuml = 0.0
+       for (l, p) in d.items():
+               cuml += p
+               if cuml > target:
+                       return l
+       return None
+
+def random_english_letter():
+       """Generate a random letter based on English letter counts
+       """
+       return weighted_choice(normalised_english_counts)
+
+
+def ngrams(text, n):
+    """Returns all n-grams of a text
+    
+    >>> ngrams(sanitise('the quick brown fox'), 2) # doctest: +NORMALIZE_WHITESPACE
+    ['th', 'he', 'eq', 'qu', 'ui', 'ic', 'ck', 'kb', 'br', 'ro', 'ow', 'wn', 
+     'nf', 'fo', 'ox']
+    >>> ngrams(sanitise('the quick brown fox'), 4) # doctest: +NORMALIZE_WHITESPACE
+    ['theq', 'hequ', 'equi', 'quic', 'uick', 'ickb', 'ckbr', 'kbro', 'brow', 
+     'rown', 'ownf', 'wnfo', 'nfox']
+    """
+    return [text[i:i+n] for i in range(len(text)-n+1)]
+
+
+class Pdist(dict):
+    """A probability distribution estimated from counts in datafile.
+    Values are stored and returned as log probabilities.
+    """
+    def __init__(self, data=[], estimate_of_missing=None):
+        data1, data2 = itertools.tee(data)
+        self.total = sum([d[1] for d in data1])
+        for key, count in data2:
+            self[key] = log10(count / self.total)
+        self.estimate_of_missing = estimate_of_missing or (lambda k, N: 1./N)
+    def __missing__(self, key):
+        return self.estimate_of_missing(key, self.total)
+
+def log_probability_of_unknown_word(key, N):
+    """Estimate the probability of an unknown word.
+    """
+    return -log10(N * 10**((len(key) - 2) * 1.4))
+
+Pw = Pdist(datafile('count_1w.txt'), log_probability_of_unknown_word)
+Pl = Pdist(datafile('count_1l.txt'), lambda _k, _N: 0)
+P2l = Pdist(datafile('count_2l.txt'), lambda _k, _N: 0)
+
+def Pwords(words): 
+    """The Naive Bayes log probability of a sequence of words.
+    """
+    return sum(Pw[w.lower()] for w in words)
+
+def Pletters(letters):
+    """The Naive Bayes log probability of a sequence of letters.
+    """
+    return sum(Pl[l.lower()] for l in letters)
+
+def Pbigrams(letters):
+    """The Naive Bayes log probability of the bigrams formed from a sequence 
+    of letters.
+    """
+    return sum(P2l[p] for p in ngrams(letters, 2))
+
+
+def cosine_distance_score(text):
+    """Finds the dissimilarity of a text to English, using the cosine distance
+    of the frequency distribution.
+
+    >>> cosine_distance_score('abcabc') # doctest: +ELLIPSIS
+    0.370847405...
+    """
+    return norms.cosine_distance(english_counts, 
+        collections.Counter(sanitise(text)))
+
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
diff --git a/lettercount.py b/lettercount.py
new file mode 100644 (file)
index 0000000..4a7082d
--- /dev/null
@@ -0,0 +1,21 @@
+import collections
+import string
+
+def sanitise(text):
+    return [l.lower() for l in text if l in string.ascii_letters]
+
+corpora = ['shakespeare.txt', 'sherlock-holmes.txt', 'war-and-peace.txt']
+counts = collections.defaultdict(int)
+
+for corpus in corpora:
+    text = sanitise(open(corpus, 'r').read())
+    for letter in text:
+        counts[letter] += 1
+
+sorted_letters = sorted(counts, key=counts.get, reverse=True)
+
+with open('count_1l.txt', 'w') as f:
+    for l in sorted_letters:
+        f.write("{0}\t{1}\n".format(l, counts[l]))
+        
+    
\ No newline at end of file
diff --git a/make-cracking-dictionary.py b/make-cracking-dictionary.py
new file mode 100644 (file)
index 0000000..37de917
--- /dev/null
@@ -0,0 +1,19 @@
+import language_models
+
+american = set(open('/usr/share/dict/american-english', 'r').readlines())
+british = set(open('/usr/share/dict/british-english', 'r').readlines())
+cracklib = set(open('/usr/share/dict/cracklib-small', 'r').readlines())
+
+words = american | british | cracklib
+
+# sanitised_words = set()
+
+# for w in words:
+    # sanitised_words.add(language_models.sanitise(w))
+    
+sanitised_words = set(language_models.sanitise(w) for w in words)
+
+sanitised_words.discard('')
+
+with open('words.txt', 'w') as f:
+    f.write('\n'.join(sorted(sanitised_words, key=lambda w: (len(w), w))))
diff --git a/norms.py b/norms.py
new file mode 100644 (file)
index 0000000..3d6d37d
--- /dev/null
+++ b/norms.py
@@ -0,0 +1,189 @@
+import collections
+from math import log10
+
+def normalise(frequencies):
+    """Scale a set of frequencies so they sum to one
+    
+    >>> sorted(normalise({1: 1, 2: 0}).items())
+    [(1, 1.0), (2, 0.0)]
+    >>> sorted(normalise({1: 1, 2: 1}).items())
+    [(1, 0.5), (2, 0.5)]
+    >>> sorted(normalise({1: 1, 2: 1, 3: 1}).items()) # doctest: +ELLIPSIS
+    [(1, 0.333...), (2, 0.333...), (3, 0.333...)]
+    >>> sorted(normalise({1: 1, 2: 2, 3: 1}).items())
+    [(1, 0.25), (2, 0.5), (3, 0.25)]
+    """
+    length = sum([f for f in frequencies.values()])
+    return collections.defaultdict(int, ((k, v / length) 
+        for (k, v) in frequencies.items()))
+
+def euclidean_scale(frequencies):
+    """Scale a set of frequencies so they have a unit euclidean length
+    
+    >>> sorted(euclidean_scale({1: 1, 2: 0}).items())
+    [(1, 1.0), (2, 0.0)]
+    >>> sorted(euclidean_scale({1: 1, 2: 1}).items()) # doctest: +ELLIPSIS
+    [(1, 0.7071067...), (2, 0.7071067...)]
+    >>> sorted(euclidean_scale({1: 1, 2: 1, 3: 1}).items()) # doctest: +ELLIPSIS
+    [(1, 0.577350...), (2, 0.577350...), (3, 0.577350...)]
+    >>> sorted(euclidean_scale({1: 1, 2: 2, 3: 1}).items()) # doctest: +ELLIPSIS
+    [(1, 0.408248...), (2, 0.81649658...), (3, 0.408248...)]
+    """
+    length = sum([f ** 2 for f in frequencies.values()]) ** 0.5
+    return collections.defaultdict(int, ((k, v / length) 
+        for (k, v) in frequencies.items()))
+
+def identity_scale(frequencies):
+    return frequencies
+        
+
+def l2(frequencies1, frequencies2):
+    """Finds the distances between two frequency profiles, expressed as dictionaries.
+    Assumes every key in frequencies1 is also in frequencies2
+    
+    >>> l2({'a':1, 'b':1, 'c':1}, {'a':1, 'b':1, 'c':1})
+    0.0
+    >>> l2({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.73205080...
+    >>> l2(normalise({'a':2, 'b':2, 'c':2}), normalise({'a':1, 'b':1, 'c':1}))
+    0.0
+    >>> l2({'a':0, 'b':2, 'c':0}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.732050807...
+    >>> l2(normalise({'a':0, 'b':2, 'c':0}), \
+           normalise({'a':1, 'b':1, 'c':1})) # doctest: +ELLIPSIS
+    0.81649658...
+    >>> l2({'a':0, 'b':1}, {'a':1, 'b':1})
+    1.0
+    """
+    total = 0
+    for k in frequencies1:
+        total += (frequencies1[k] - frequencies2[k]) ** 2
+    return total ** 0.5
+euclidean_distance = l2
+
+def l1(frequencies1, frequencies2):
+    """Finds the distances between two frequency profiles, expressed as 
+    dictionaries. Assumes every key in frequencies1 is also in frequencies2
+
+    >>> l1({'a':1, 'b':1, 'c':1}, {'a':1, 'b':1, 'c':1})
+    0
+    >>> l1({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1})
+    3
+    >>> l1(normalise({'a':2, 'b':2, 'c':2}), normalise({'a':1, 'b':1, 'c':1}))
+    0.0
+    >>> l1({'a':0, 'b':2, 'c':0}, {'a':1, 'b':1, 'c':1})
+    3
+    >>> l1({'a':0, 'b':1}, {'a':1, 'b':1})
+    1
+    """
+    total = 0
+    for k in frequencies1:
+        total += abs(frequencies1[k] - frequencies2[k])
+    return total
+
+def l3(frequencies1, frequencies2):
+    """Finds the distances between two frequency profiles, expressed as 
+    dictionaries. Assumes every key in frequencies1 is also in frequencies2
+
+    >>> l3({'a':1, 'b':1, 'c':1}, {'a':1, 'b':1, 'c':1})
+    0.0
+    >>> l3({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.44224957...
+    >>> l3({'a':0, 'b':2, 'c':0}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.4422495703...
+    >>> l3(normalise({'a':0, 'b':2, 'c':0}), \
+           normalise({'a':1, 'b':1, 'c':1})) # doctest: +ELLIPSIS
+    0.718144896...
+    >>> l3({'a':0, 'b':1}, {'a':1, 'b':1})
+    1.0
+    >>> l3(normalise({'a':0, 'b':1}), normalise({'a':1, 'b':1})) # doctest: +ELLIPSIS
+    0.6299605249...
+    """
+    total = 0
+    for k in frequencies1:
+        total += abs(frequencies1[k] - frequencies2[k]) ** 3
+    return total ** (1/3)
+
+def geometric_mean(frequencies1, frequencies2):
+    """Finds the geometric mean of the absolute differences between two frequency profiles, 
+    expressed as dictionaries.
+    Assumes every key in frequencies1 is also in frequencies2
+    
+    >>> geometric_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1})
+    1
+    >>> geometric_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1})
+    1
+    >>> geometric_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':5, 'c':1})
+    3
+    >>> geometric_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                       normalise({'a':1, 'b':5, 'c':1})) # doctest: +ELLIPSIS
+    0.01382140...
+    >>> geometric_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                       normalise({'a':1, 'b':1, 'c':1})) # doctest: +ELLIPSIS
+    0.0
+    >>> geometric_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                       normalise({'a':1, 'b':1, 'c':0})) # doctest: +ELLIPSIS
+    0.009259259...
+    """
+    total = 1
+    for k in frequencies1:
+        total *= abs(frequencies1[k] - frequencies2[k])
+    return total
+
+def harmonic_mean(frequencies1, frequencies2):
+    """Finds the harmonic mean of the absolute differences between two frequency profiles, 
+    expressed as dictionaries.
+    Assumes every key in frequencies1 is also in frequencies2
+
+    >>> harmonic_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1})
+    1.0
+    >>> harmonic_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1})
+    1.0
+    >>> harmonic_mean({'a':2, 'b':2, 'c':2}, {'a':1, 'b':5, 'c':1}) # doctest: +ELLIPSIS
+    1.285714285...
+    >>> harmonic_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                      normalise({'a':1, 'b':5, 'c':1})) # doctest: +ELLIPSIS
+    0.228571428571...
+    >>> harmonic_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                      normalise({'a':1, 'b':1, 'c':1})) # doctest: +ELLIPSIS
+    0
+    >>> harmonic_mean(normalise({'a':2, 'b':2, 'c':2}), \
+                      normalise({'a':1, 'b':1, 'c':0})) # doctest: +ELLIPSIS
+    0.2
+    """
+    total = 0
+    for k in frequencies1:
+        if abs(frequencies1[k] - frequencies2[k]) == 0:
+            return 0
+        total += 1 / abs(frequencies1[k] - frequencies2[k])
+    return len(frequencies1) / total
+
+
+def cosine_distance(frequencies1, frequencies2):
+    """Finds the distances between two frequency profiles, expressed as dictionaries.
+    Assumes every key in frequencies1 is also in frequencies2
+
+    >>> cosine_distance({'a':1, 'b':1, 'c':1}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.0000000000...
+    >>> cosine_distance({'a':2, 'b':2, 'c':2}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    1.0000000000...
+    >>> cosine_distance({'a':0, 'b':2, 'c':0}, {'a':1, 'b':1, 'c':1}) # doctest: +ELLIPSIS
+    0.5773502691...
+    >>> cosine_distance({'a':0, 'b':1}, {'a':1, 'b':1}) # doctest: +ELLIPSIS
+    0.7071067811...
+    """
+    numerator = 0
+    length1 = 0
+    length2 = 0
+    for k in frequencies1:
+        numerator += frequencies1[k] * frequencies2[k]
+        length1 += frequencies1[k]**2
+    for k in frequencies2.keys():
+        length2 += frequencies2[k]
+    return numerator / (length1 ** 0.5 * length2 ** 0.5)
+
+
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()
diff --git a/segment.py b/segment.py
new file mode 100644 (file)
index 0000000..ba3ddd7
--- /dev/null
@@ -0,0 +1,19 @@
+import language_models
+import sys
+from functools import lru_cache
+sys.setrecursionlimit(1000000)
+
+@lru_cache()
+def segment(text):
+    """Return a list of words that is the best segmentation of text.
+    """
+    if not text: return []
+    candidates = ([first]+segment(rest) for first,rest in splits(text))
+    return max(candidates, key=language_models.Pwords)
+
+def splits(text, L=20):
+    """Return a list of all possible (first, rest) pairs, len(first)<=L.
+    """
+    return [(text[:i+1], text[i+1:]) 
+            for i in range(min(len(text), L))]
+
diff --git a/unknown-word-probability-investigation.ipynb b/unknown-word-probability-investigation.ipynb
new file mode 100644 (file)
index 0000000..cba89bf
--- /dev/null
@@ -0,0 +1,179 @@
+{
+ "metadata": {
+  "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%matplotlib inline\n",
+      "import matplotlib.pyplot as plt\n",
+      "from math import log10\n",
+      "from cipherbreak import *\n",
+      "from language_models import *"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "fractions = [1.0]\n",
+      "for wordlen in range(1, 20):\n",
+      "    known_words = len([w for w in keywords if len(w) == wordlen])\n",
+      "    possible_words = 26 ** wordlen\n",
+      "    fractions += [known_words / possible_words]\n",
+      "fractions"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 2,
+       "text": [
+        "[1.0,\n",
+        " 1.0,\n",
+        " 0.34615384615384615,\n",
+        " 0.05974055530268548,\n",
+        " 0.007654668954168271,\n",
+        " 0.0005913456488541394,\n",
+        " 3.6129588927177356e-05,\n",
+        " 1.8010883826943671e-06,\n",
+        " 7.107795165409739e-08,\n",
+        " 2.4355817367258945e-09,\n",
+        " 7.469162662303339e-11,\n",
+        " 1.979378237044537e-12,\n",
+        " 4.875878520286003e-14,\n",
+        " 1.1095648437193016e-15,\n",
+        " 2.199659830168053e-17,\n",
+        " 4.185399254019551e-19,\n",
+        " 6.83349209784038e-21,\n",
+        " 1.199477188056649e-22,\n",
+        " 2.0013901045062867e-24,\n",
+        " 1.5656245928341226e-26]"
+       ]
+      }
+     ],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plt.plot(fractions)\n",
+      "plt.ylabel(\"Probability of word\")\n",
+      "plt.xlabel(\"Word length\")\n",
+      "plt.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\nA6P5Ivy3tPMPAAAAAElFTkSuQmCC\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0x7fbd43167f50>"
+       ]
+      }
+     ],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plt.plot([log10(f) for f in fractions])\n",
+      "plt.plot([log10(f) for f in fractions], 'bo')\n",
+      "plt.ylabel(\"Log probability of word\")\n",
+      "plt.xlabel(\"Word length\")\n",
+      "plt.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0x7fbd42238b90>"
+       ]
+      }
+     ],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plt.plot([log10(f) for f in fractions], 'bo')\n",
+      "plt.plot([i for i in range(2,20)], [-(i-2) for i in range(2,20)], 'g-')\n",
+      "plt.ylabel(\"Log probability of word\")\n",
+      "plt.xlabel(\"Word length\")\n",
+      "plt.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\n/w+H/CoI41pxawAAAABJRU5ErkJggg==\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0x7fbd541147d0>"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "plt.plot([log10(f) for f in fractions], 'bo')\n",
+      "plt.plot([i for i in range(2,20)], [-(i-2) for i in range(2,20)], 'g-')\n",
+      "plt.plot([i for i in range(2,20)], [-(i-3)*1.5 for i in range(2,20)], 'r-')\n",
+      "plt.plot([i for i in range(2,20)], [-(i-2)*1.4 for i in range(2,20)], 'r^-')\n",
+      "plt.ylabel(\"Log probability of word\")\n",
+      "plt.xlabel(\"Word length\")\n",
+      "plt.show()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "display_data",
+       "png": "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\n",
+       "text": [
+        "<matplotlib.figure.Figure at 0x7fbd414c8910>"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 6
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file