+{
+ "metadata": {
+ "name": "",
+ "signature": "sha256:c52a83147f45ed889200fe19a5d4ec4422e884758e7d8a11536fbaafa6c627ee"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "import matplotlib.pyplot as plt\n",
+ "import pandas as pd\n",
+ "import collections\n",
+ "import string\n",
+ "import numpy as np\n",
+ "from numpy import matrix\n",
+ "from numpy import linalg\n",
+ "%matplotlib inline\n",
+ "\n",
+ "from cipher import *\n",
+ "from cipherbreak import *\n",
+ "\n",
+ "c8a = open('2014/8a.ciphertext').read().strip()\n",
+ "c8b = open('2014/8b.ciphertext').read().strip()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 4
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def cadenus_letter(n, doubled='v'):\n",
+ " letter = chr(n + ord('a'))\n",
+ " if letter > doubled:\n",
+ " letter = chr(n + ord('a') + 1)\n",
+ " return letter"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 2
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "c8bl = ''.join([cadenus_letter(int(c, 2)) for c in chunks(c8b, 5)])\n",
+ "c8bl"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 5,
+ "text": [
+ "'afcaeuottacthrioletcserthshtrahkzorpfrgeoadppjnglternefeofiortsddoeeumscruernfetlaafstxientrvoonerhuahravereetsvsielhlostdoalozaesmnndignnrhohhtsnaoilncnssicreanneeiiierxtanesrvogieizxssdgpvoiaisaoaeoaedrnitrnyeigrpsshadhdtoipaateyennesagrobtlesrnroirzpbgedcllixalaleenigrrnxzrlimlpstoleftrdmuarieeeiiaolnexsaohrtlstobetnslvfivdovtpoaeeisciohipseveedtexfarnhebleaotohtttepnckaonhxetmvzprreonnasgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfysoaotctbbsoeirnsadlztrrunrceptthreuhnktaceceelrxnireeeaeseeeidisogceomnrtejhagabsenitlxtrnbmielsaretesrngsnhebiosdienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnzpaidziegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlevasadnnthneiteiisahuhhuamonefzhlonxhaeeeeosneezaneisetogziterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseizclsiantaoltcizmidentthltndytttmasbleaeetlisirtxturpfailteaoefeisiiizisikvtxisprbsinelphrmohiagnlslvitodaisdpnzddcaaotahcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmuppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienniklzsogstcifzpipvidvssmnceiasiitsnneatitomrhbnhnidprlrepoznalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghznxeintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaozaanoeeldoinhusgiteaoriecevemntratmtfpeucutahamtnexonicdeemrpaolitoafesoosspfnlneeootachllirssysofpdftfrnpraeeazlonahautntcntcbaxloneftoatecvoxdlxvnneedtiioigtegmtaheeatefaaeprrcrosheerrpalediengidrreouhvesuroztnsosinuiuiofprda'"
+ ]
+ }
+ ],
+ "prompt_number": 5
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "c8bgrid = chunks(c8bl, int(len(c8bl) / 25))\n",
+ "c8bgrid"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 9,
+ "text": [
+ "['afcaeuottacthrioletcserthshtrahkzorpfrgeoadppjnglternefe',\n",
+ " 'ofiortsddoeeumscruernfetlaafstxientrvoonerhuahravereetsv',\n",
+ " 'sielhlostdoalozaesmnndignnrhohhtsnaoilncnssicreanneeiiie',\n",
+ " 'rxtanesrvogieizxssdgpvoiaisaoaeoaedrnitrnyeigrpsshadhdto',\n",
+ " 'ipaateyennesagrobtlesrnroirzpbgedcllixalaleenigrrnxzrlim',\n",
+ " 'lpstoleftrdmuarieeeiiaolnexsaohrtlstobetnslvfivdovtpoaee',\n",
+ " 'isciohipseveedtexfarnhebleaotohtttepnckaonhxetmvzprreonn',\n",
+ " 'asgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfys',\n",
+ " 'oaotctbbsoeirnsadlztrrunrceptthreuhnktaceceelrxnireeeaes',\n",
+ " 'eeeidisogceomnrtejhagabsenitlxtrnbmielsaretesrngsnhebios',\n",
+ " 'dienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnzpai',\n",
+ " 'dziegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlev',\n",
+ " 'asadnnthneiteiisahuhhuamonefzhlonxhaeeeeosneezaneisetogz',\n",
+ " 'iterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseizclsian',\n",
+ " 'taoltcizmidentthltndytttmasbleaeetlisirtxturpfailteaoefe',\n",
+ " 'isiiizisikvtxisprbsinelphrmohiagnlslvitodaisdpnzddcaaota',\n",
+ " 'hcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmu',\n",
+ " 'ppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienni',\n",
+ " 'klzsogstcifzpipvidvssmnceiasiitsnneatitomrhbnhnidprlrepo',\n",
+ " 'znalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghzn',\n",
+ " 'xeintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaozaa',\n",
+ " 'noeeldoinhusgiteaoriecevemntratmtfpeucutahamtnexonicdeem',\n",
+ " 'rpaolitoafesoosspfnlneeootachllirssysofpdftfrnpraeeazlon',\n",
+ " 'ahautntcntcbaxloneftoatecvoxdlxvnneedtiioigtegmtaheeatef',\n",
+ " 'aaeprrcrosheerrpalediengidrreouhvesuroztnsosinuiuiofprda']"
+ ]
+ }
+ ],
+ "prompt_number": 9
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "len(c8bgrid[0])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 11,
+ "text": [
+ "56"
+ ]
+ }
+ ],
+ "prompt_number": 11
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def make_keycolumn(doubled_letters = 'vw', start='a', reverse=False):\n",
+ " index_to_remove = string.ascii_lowercase.find(doubled_letters[0])\n",
+ " short_alphabet = string.ascii_lowercase[:index_to_remove] + string.ascii_lowercase[index_to_remove+1:]\n",
+ " if reverse:\n",
+ " short_alphabet = ''.join(reversed(short_alphabet))\n",
+ " start_pos = short_alphabet.find(start)\n",
+ " rotated_alphabet = short_alphabet[start_pos:] + short_alphabet[:start_pos]\n",
+ " keycolumn = {l: i for i, l in enumerate(rotated_alphabet)}\n",
+ " keycolumn[doubled_letters[0]] = keycolumn[doubled_letters[1]]\n",
+ " return keycolumn"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 75
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "pt = sanitise(\"Whoever has made a voyage up the Hudson must remember the Kaatskill mountains. They are a dismembered branch of the great\")\n",
+ "keyword = 'wink'"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 36
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "keycolumn = make_keycolumn(reverse=True)\n",
+ "[(k, keycolumn[k]) for k in sorted(keycolumn)]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 103,
+ "text": [
+ "[('a', 0),\n",
+ " ('b', 24),\n",
+ " ('c', 23),\n",
+ " ('d', 22),\n",
+ " ('e', 21),\n",
+ " ('f', 20),\n",
+ " ('g', 19),\n",
+ " ('h', 18),\n",
+ " ('i', 17),\n",
+ " ('j', 16),\n",
+ " ('k', 15),\n",
+ " ('l', 14),\n",
+ " ('m', 13),\n",
+ " ('n', 12),\n",
+ " ('o', 11),\n",
+ " ('p', 10),\n",
+ " ('q', 9),\n",
+ " ('r', 8),\n",
+ " ('s', 7),\n",
+ " ('t', 6),\n",
+ " ('u', 5),\n",
+ " ('v', 4),\n",
+ " ('w', 4),\n",
+ " ('x', 3),\n",
+ " ('y', 2),\n",
+ " ('z', 1)]"
+ ]
+ }
+ ],
+ "prompt_number": 103
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "keycolumn = make_keycolumn(doubled_letters='ij', start='b', reverse=True)\n",
+ "[(k, keycolumn[k]) for k in sorted(keycolumn)]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 101,
+ "text": [
+ "[('a', 1),\n",
+ " ('b', 0),\n",
+ " ('c', 24),\n",
+ " ('d', 23),\n",
+ " ('e', 22),\n",
+ " ('f', 21),\n",
+ " ('g', 20),\n",
+ " ('h', 19),\n",
+ " ('i', 18),\n",
+ " ('j', 18),\n",
+ " ('k', 17),\n",
+ " ('l', 16),\n",
+ " ('m', 15),\n",
+ " ('n', 14),\n",
+ " ('o', 13),\n",
+ " ('p', 12),\n",
+ " ('q', 11),\n",
+ " ('r', 10),\n",
+ " ('s', 9),\n",
+ " ('t', 8),\n",
+ " ('u', 7),\n",
+ " ('v', 6),\n",
+ " ('w', 5),\n",
+ " ('x', 4),\n",
+ " ('y', 3),\n",
+ " ('z', 2)]"
+ ]
+ }
+ ],
+ "prompt_number": 101
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "pt_rows = chunks(pt, len(pt) // 25, fillvalue='a')\n",
+ "pt_rows"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 15,
+ "text": [
+ "['whoe',\n",
+ " 'verh',\n",
+ " 'asma',\n",
+ " 'deav',\n",
+ " 'oyag',\n",
+ " 'eupt',\n",
+ " 'hehu',\n",
+ " 'dson',\n",
+ " 'must',\n",
+ " 'reme',\n",
+ " 'mber',\n",
+ " 'thek',\n",
+ " 'aats',\n",
+ " 'kill',\n",
+ " 'moun',\n",
+ " 'tain',\n",
+ " 'sthe',\n",
+ " 'yare',\n",
+ " 'adis',\n",
+ " 'memb',\n",
+ " 'ered',\n",
+ " 'bran',\n",
+ " 'chof',\n",
+ " 'theg',\n",
+ " 'reat']"
+ ]
+ }
+ ],
+ "prompt_number": 15
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "[keycolumn[l] for l in keyword]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 38,
+ "text": [
+ "[21, 8, 13, 10]"
+ ]
+ }
+ ],
+ "prompt_number": 38
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "pt_columns = [''.join(c) for c in zip(*pt_rows)]\n",
+ "pt_columns"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 47,
+ "text": [
+ "['wvadoehdmrmtakmtsyamebctr',\n",
+ " 'heseyuesuebhaioataderrhhe',\n",
+ " 'ormaaphosmeetluihrimeaoea',\n",
+ " 'ehavgtunterkslnneesbdnfgt']"
+ ]
+ }
+ ],
+ "prompt_number": 47
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "rotated_pt_columns = [''.join(col[start:] + col[:start]) for start, col in zip([keycolumn[l] for l in keyword], pt_columns)] \n",
+ "rotated_pt_rows = zip(*rotated_pt_columns)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 78
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "transpositions = transpositions_of(keyword)\n",
+ "transposed = [transpose(r, transpositions) for r in rotated_pt_rows]\n",
+ "transposed"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 79,
+ "text": [
+ "[['a', 'n', 't', 'o'],\n",
+ " ['d', 'e', 'l', 'e'],\n",
+ " ['e', 'e', 'u', 'h'],\n",
+ " ['r', 's', 'i', 'd'],\n",
+ " ['r', 'b', 'h', 'm'],\n",
+ " ['h', 'd', 'r', 'r'],\n",
+ " ['h', 'n', 'i', 'm'],\n",
+ " ['e', 'f', 'm', 't'],\n",
+ " ['h', 'g', 'e', 'a'],\n",
+ " ['e', 't', 'a', 'k'],\n",
+ " ['s', 'e', 'o', 'm'],\n",
+ " ['e', 'h', 'e', 't'],\n",
+ " ['y', 'a', 'a', 's'],\n",
+ " ['u', 'v', 'o', 'y'],\n",
+ " ['e', 'g', 'r', 'a'],\n",
+ " ['s', 't', 'm', 'm'],\n",
+ " ['u', 'u', 'a', 'e'],\n",
+ " ['e', 'n', 'a', 'b'],\n",
+ " ['b', 't', 'p', 'c'],\n",
+ " ['h', 'e', 'h', 't'],\n",
+ " ['a', 'r', 'o', 'r'],\n",
+ " ['i', 'k', 's', 'w'],\n",
+ " ['o', 's', 'm', 'v'],\n",
+ " ['a', 'l', 'e', 'a'],\n",
+ " ['t', 'n', 'e', 'd']]"
+ ]
+ }
+ ],
+ "prompt_number": 79
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def cadenus_encipher(message, keyword, keycolumn, fillvalue='a'):\n",
+ " rows = chunks(message, len(message) // 25, fillvalue=fillvalue)\n",
+ " columns = zip(*rows)\n",
+ " rotated_columns = [col[start:] + col[:start] for start, col in zip([keycolumn[l] for l in keyword], columns)] \n",
+ " rotated_rows = zip(*rotated_columns)\n",
+ " transpositions = transpositions_of(keyword)\n",
+ " transposed = [transpose(r, transpositions) for r in rotated_rows]\n",
+ " return ''.join(chain(*transposed))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 82
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "cadenus_encipher(pt, 'wink', make_keycolumn(reverse=True))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 104,
+ "text": [
+ "'antodeleeeuhrsidrbhmhdrrhnimefmthgeaetakseomehetyaasuvoyegrastmmuuaeenabbtpchehtarorikswosmvaleatned'"
+ ]
+ }
+ ],
+ "prompt_number": 104
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "cadenus_encipher(sanitise('a severe limitation on the usefulness of the cadenus ' \n",
+ " 'is that every message must be a multiple of twenty-five '\n",
+ " 'letters long'), 'easy', make_keycolumn(reverse=True))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 105,
+ "text": [
+ "'systretomtattlusoatleeesfiyheasdfnmschbhneuvsnpmtofarenuseieeieltarlmentieetogevesitfaisltngeeuvowul'"
+ ]
+ }
+ ],
+ "prompt_number": 105
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def cadenus_decipher(message, keyword, keycolumn, fillvalue='a'):\n",
+ " rows = chunks(message, len(message) // 25, fillvalue=fillvalue)\n",
+ " transpositions = transpositions_of(keyword)\n",
+ " untransposed_rows = [untranspose(r, transpositions) for r in rows]\n",
+ " columns = zip(*untransposed_rows)\n",
+ " rotated_columns = [col[-start:] + col[:-start] for start, col in zip([keycolumn[l] for l in keyword], columns)] \n",
+ " rotated_rows = zip(*rotated_columns)\n",
+ " # return rotated_columns\n",
+ " return ''.join(chain(*rotated_rows))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 93
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ " cadenus_decipher('antodeleeeuhrsidrbhmhdrrhnimefmthgeaetakseomehetyaasuvoyegrastmmuuaeenabbtpchehtarorikswosmvaleatned',\n",
+ " 'wink',\n",
+ " make_keycolumn(reverse=True))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 106,
+ "text": [
+ "'whoeverhasmadeavoyageupthehudsonmustrememberthekaatskillmountainstheyareadismemberedbranchofthegreat'"
+ ]
+ }
+ ],
+ "prompt_number": 106
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ " cadenus_decipher('systretomtattlusoatleeesfiyheasdfnmschbhneuvsnpmtofarenuseieeieltarlmentieetogevesitfaisltngeeuvowul',\n",
+ " 'easy',\n",
+ " make_keycolumn(reverse=True))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 107,
+ "text": [
+ "'aseverelimitationontheusefulnessofthecadenusisthateverymessagemustbeamultipleoftwentyfiveletterslong'"
+ ]
+ }
+ ],
+ "prompt_number": 107
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": []
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
\ No newline at end of file