X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=cadenus-ciphers.ipynb;fp=cadenus-ciphers.ipynb;h=40b4dc40815cc8ff8c3356f4c9b0b925b92c86c5;hb=c4e708c39107fc0065684ceed82c6b53a0640a81;hp=0000000000000000000000000000000000000000;hpb=8eb6246a9b4f99e6b3cd68047e6cef21289417ec;p=cipher-tools.git diff --git a/cadenus-ciphers.ipynb b/cadenus-ciphers.ipynb new file mode 100644 index 0000000..40b4dc4 --- /dev/null +++ b/cadenus-ciphers.ipynb @@ -0,0 +1,542 @@ +{ + "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