import math
from enum import Enum
from itertools import zip_longest, cycle, chain
+import numpy as np
+from numpy import matrix
+from numpy import linalg
from language_models import *
return ''.join(c for r in zip_longest(*(down_rows + up_rows), fillvalue='') for c in r)
+def hill_encipher(matrix, message_letters, fillvalue='a'):
+ """Hill cipher
+
+ >>> hill_encipher(np.matrix([[7,8], [11,11]]), 'hellothere')
+ 'drjiqzdrvx'
+ >>> hill_encipher(np.matrix([[6, 24, 1], [13, 16, 10], [20, 17, 15]]), \
+ 'hello there')
+ 'tfjflpznvyac'
+ """
+ n = len(matrix)
+ sanitised_message = sanitise(message_letters)
+ if len(sanitised_message) % n != 0:
+ padding = fillvalue[0] * (n - len(sanitised_message) % n)
+ else:
+ padding = ''
+ message = [ord(c) - ord('a') for c in sanitised_message + padding]
+ message_chunks = [message[i:i+n] for i in range(0, len(message), n)]
+ # message_chunks = chunks(message, len(matrix), fillvalue=None)
+ enciphered_chunks = [((matrix * np.matrix(c).T).T).tolist()[0]
+ for c in message_chunks]
+ return ''.join([chr(int(round(l)) % 26 + ord('a'))
+ for l in sum(enciphered_chunks, [])])
+
+
+def hill_decipher(matrix, message, fillvalue='a'):
+ """Hill cipher
+
+ >>> hill_decipher(np.matrix([[7,8], [11,11]]), 'drjiqzdrvx')
+ 'hellothere'
+ >>> hill_decipher(np.matrix([[6, 24, 1], [13, 16, 10], [20, 17, 15]]), \
+ 'tfjflpznvyac')
+ 'hellothereaa'
+ """
+ adjoint = linalg.det(matrix)*linalg.inv(matrix)
+ inverse_determinant = modular_division_table[int(round(linalg.det(matrix))) % 26][1]
+ inverse_matrix = (inverse_determinant * adjoint) % 26
+ return hill_encipher(inverse_matrix, message, fillvalue)
+
class PocketEnigma(object):
"""A pocket enigma machine
The wheel is internally represented as a 26-element list self.wheel_map,
--- /dev/null
+{
+ "metadata": {
+ "name": "",
+ "signature": "sha256:0fe9165e4a65606dd93377df5e8d4ccf8671a4edf4adc8d5da4b33f83316516f"
+ },
+ "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",
+ "c6a = open('2014/6a.ciphertext').read()\n",
+ "c6b = open('2014/6b.ciphertext').read()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 54
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "key_a, score = railfence_break(sanitise(c6a))\n",
+ "key_a, score"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 3,
+ "text": [
+ "(3, -2314.997881051078)"
+ ]
+ }
+ ],
+ "prompt_number": 3
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "' '.join(segment(railfence_decipher(sanitise(c6a), key_a)))"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 4,
+ "text": [
+ "'mark the last message told usa lot the scuttling equipment is designed to pump water in and out of the vessel like a submarine dive control but clearly they werent planning to turn a container ship into a sub this ship is a largescale version of something i have seen in the caribbean drug runners use a similar technique to get below radar coverage for inshore runs sinking the vessel so that the deck remains just below the wave tops the fda pirates seem more interested in staying away from shore but getting close enough to track and record electronic communications without detection i am guessing this scuttling system is what they call nautilus in their log but i am still baffled by the references to seahorse the next page of the log looks harder to crack but the cipher clerk tells me it is a hill cipher and that they must have been in a hurry or have been enciphering by hand since they just used a two by two matrix actually we have been pretty lax with our security and i think the next message is end will use avi genere cipher given that we are using secure cables i dont think we have too much to worry about so i will keep the keyword short say three characters more later harry'"
+ ]
+ }
+ ],
+ "prompt_number": 4
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "c6bs = sanitise(c6b)\n",
+ "c6bs"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 7,
+ "text": [
+ "'hwssswxfewhhrfewpdrvttdhxbccleayphalnadhiehaoudrotwnrrvysabjlttbaytmelrkaidopthatlelrtwaamaneksvvzrvllatkcrjquicizgtoqcpnrrkttowandqehtqrvtbaydqealannohulanuzlwextlvjrvivhnohdqmgykaclmswrupdetfioftfelhzpxhaswftwprrsweiseohefpdrvttnvagdvswgoerbetnharvaeevtlltbmgaiatgelinmdawevhatterdhrznbnvoutnefoteveaehlaymhacglzeptvvdimworfisgtuzlwibeqohubtghamqornjnnrumqvjtxeltfovgawdaeevllgrtxibgtibevmpsaateoasevaeyqohameonncfuidoefafattemuimnflznbekofobrliaehhauihnnnwzaeevtlltpaalnanvtzlzuucptaelinanpaahewfthaosetaribnbnvhaevdhyytlmuxb'"
+ ]
+ }
+ ],
+ "prompt_number": 7
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "c6b_nums = [ord(c) - ord('a') for c in c6bs]\n",
+ "c6b_nums"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 17,
+ "text": [
+ "[7,\n",
+ " 22,\n",
+ " 18,\n",
+ " 18,\n",
+ " 18,\n",
+ " 22,\n",
+ " 23,\n",
+ " 5,\n",
+ " 4,\n",
+ " 22,\n",
+ " 7,\n",
+ " 7,\n",
+ " 17,\n",
+ " 5,\n",
+ " 4,\n",
+ " 22,\n",
+ " 15,\n",
+ " 3,\n",
+ " 17,\n",
+ " 21,\n",
+ " 19,\n",
+ " 19,\n",
+ " 3,\n",
+ " 7,\n",
+ " 23,\n",
+ " 1,\n",
+ " 2,\n",
+ " 2,\n",
+ " 11,\n",
+ " 4,\n",
+ " 0,\n",
+ " 24,\n",
+ " 15,\n",
+ " 7,\n",
+ " 0,\n",
+ " 11,\n",
+ " 13,\n",
+ " 0,\n",
+ " 3,\n",
+ " 7,\n",
+ " 8,\n",
+ " 4,\n",
+ " 7,\n",
+ " 0,\n",
+ " 14,\n",
+ " 20,\n",
+ " 3,\n",
+ " 17,\n",
+ " 14,\n",
+ " 19,\n",
+ " 22,\n",
+ " 13,\n",
+ " 17,\n",
+ " 17,\n",
+ " 21,\n",
+ " 24,\n",
+ " 18,\n",
+ " 0,\n",
+ " 1,\n",
+ " 9,\n",
+ " 11,\n",
+ " 19,\n",
+ " 19,\n",
+ " 1,\n",
+ " 0,\n",
+ " 24,\n",
+ " 19,\n",
+ " 12,\n",
+ " 4,\n",
+ " 11,\n",
+ " 17,\n",
+ " 10,\n",
+ " 0,\n",
+ " 8,\n",
+ " 3,\n",
+ " 14,\n",
+ " 15,\n",
+ " 19,\n",
+ " 7,\n",
+ " 0,\n",
+ " 19,\n",
+ " 11,\n",
+ " 4,\n",
+ " 11,\n",
+ " 17,\n",
+ " 19,\n",
+ " 22,\n",
+ " 0,\n",
+ " 0,\n",
+ " 12,\n",
+ " 0,\n",
+ " 13,\n",
+ " 4,\n",
+ " 10,\n",
+ " 18,\n",
+ " 21,\n",
+ " 21,\n",
+ " 25,\n",
+ " 17,\n",
+ " 21,\n",
+ " 11,\n",
+ " 11,\n",
+ " 0,\n",
+ " 19,\n",
+ " 10,\n",
+ " 2,\n",
+ " 17,\n",
+ " 9,\n",
+ " 16,\n",
+ " 20,\n",
+ " 8,\n",
+ " 2,\n",
+ " 8,\n",
+ " 25,\n",
+ " 6,\n",
+ " 19,\n",
+ " 14,\n",
+ " 16,\n",
+ " 2,\n",
+ " 15,\n",
+ " 13,\n",
+ " 17,\n",
+ " 17,\n",
+ " 10,\n",
+ " 19,\n",
+ " 19,\n",
+ " 14,\n",
+ " 22,\n",
+ " 0,\n",
+ " 13,\n",
+ " 3,\n",
+ " 16,\n",
+ " 4,\n",
+ " 7,\n",
+ " 19,\n",
+ " 16,\n",
+ " 17,\n",
+ " 21,\n",
+ " 19,\n",
+ " 1,\n",
+ " 0,\n",
+ " 24,\n",
+ " 3,\n",
+ " 16,\n",
+ " 4,\n",
+ " 0,\n",
+ " 11,\n",
+ " 0,\n",
+ " 13,\n",
+ " 13,\n",
+ " 14,\n",
+ " 7,\n",
+ " 20,\n",
+ " 11,\n",
+ " 0,\n",
+ " 13,\n",
+ " 20,\n",
+ " 25,\n",
+ " 11,\n",
+ " 22,\n",
+ " 4,\n",
+ " 23,\n",
+ " 19,\n",
+ " 11,\n",
+ " 21,\n",
+ " 9,\n",
+ " 17,\n",
+ " 21,\n",
+ " 8,\n",
+ " 21,\n",
+ " 7,\n",
+ " 13,\n",
+ " 14,\n",
+ " 7,\n",
+ " 3,\n",
+ " 16,\n",
+ " 12,\n",
+ " 6,\n",
+ " 24,\n",
+ " 10,\n",
+ " 0,\n",
+ " 2,\n",
+ " 11,\n",
+ " 12,\n",
+ " 18,\n",
+ " 22,\n",
+ " 17,\n",
+ " 20,\n",
+ " 15,\n",
+ " 3,\n",
+ " 4,\n",
+ " 19,\n",
+ " 5,\n",
+ " 8,\n",
+ " 14,\n",
+ " 5,\n",
+ " 19,\n",
+ " 5,\n",
+ " 4,\n",
+ " 11,\n",
+ " 7,\n",
+ " 25,\n",
+ " 15,\n",
+ " 23,\n",
+ " 7,\n",
+ " 0,\n",
+ " 18,\n",
+ " 22,\n",
+ " 5,\n",
+ " 19,\n",
+ " 22,\n",
+ " 15,\n",
+ " 17,\n",
+ " 17,\n",
+ " 18,\n",
+ " 22,\n",
+ " 4,\n",
+ " 8,\n",
+ " 18,\n",
+ " 4,\n",
+ " 14,\n",
+ " 7,\n",
+ " 4,\n",
+ " 5,\n",
+ " 15,\n",
+ " 3,\n",
+ " 17,\n",
+ " 21,\n",
+ " 19,\n",
+ " 19,\n",
+ " 13,\n",
+ " 21,\n",
+ " 0,\n",
+ " 6,\n",
+ " 3,\n",
+ " 21,\n",
+ " 18,\n",
+ " 22,\n",
+ " 6,\n",
+ " 14,\n",
+ " 4,\n",
+ " 17,\n",
+ " 1,\n",
+ " 4,\n",
+ " 19,\n",
+ " 13,\n",
+ " 7,\n",
+ " 0,\n",
+ " 17,\n",
+ " 21,\n",
+ " 0,\n",
+ " 4,\n",
+ " 4,\n",
+ " 21,\n",
+ " 19,\n",
+ " 11,\n",
+ " 11,\n",
+ " 19,\n",
+ " 1,\n",
+ " 12,\n",
+ " 6,\n",
+ " 0,\n",
+ " 8,\n",
+ " 0,\n",
+ " 19,\n",
+ " 6,\n",
+ " 4,\n",
+ " 11,\n",
+ " 8,\n",
+ " 13,\n",
+ " 12,\n",
+ " 3,\n",
+ " 0,\n",
+ " 22,\n",
+ " 4,\n",
+ " 21,\n",
+ " 7,\n",
+ " 0,\n",
+ " 19,\n",
+ " 19,\n",
+ " 4,\n",
+ " 17,\n",
+ " 3,\n",
+ " 7,\n",
+ " 17,\n",
+ " 25,\n",
+ " 13,\n",
+ " 1,\n",
+ " 13,\n",
+ " 21,\n",
+ " 14,\n",
+ " 20,\n",
+ " 19,\n",
+ " 13,\n",
+ " 4,\n",
+ " 5,\n",
+ " 14,\n",
+ " 19,\n",
+ " 4,\n",
+ " 21,\n",
+ " 4,\n",
+ " 0,\n",
+ " 4,\n",
+ " 7,\n",
+ " 11,\n",
+ " 0,\n",
+ " 24,\n",
+ " 12,\n",
+ " 7,\n",
+ " 0,\n",
+ " 2,\n",
+ " 6,\n",
+ " 11,\n",
+ " 25,\n",
+ " 4,\n",
+ " 15,\n",
+ " 19,\n",
+ " 21,\n",
+ " 21,\n",
+ " 3,\n",
+ " 8,\n",
+ " 12,\n",
+ " 22,\n",
+ " 14,\n",
+ " 17,\n",
+ " 5,\n",
+ " 8,\n",
+ " 18,\n",
+ " 6,\n",
+ " 19,\n",
+ " 20,\n",
+ " 25,\n",
+ " 11,\n",
+ " 22,\n",
+ " 8,\n",
+ " 1,\n",
+ " 4,\n",
+ " 16,\n",
+ " 14,\n",
+ " 7,\n",
+ " 20,\n",
+ " 1,\n",
+ " 19,\n",
+ " 6,\n",
+ " 7,\n",
+ " 0,\n",
+ " 12,\n",
+ " 16,\n",
+ " 14,\n",
+ " 17,\n",
+ " 13,\n",
+ " 9,\n",
+ " 13,\n",
+ " 13,\n",
+ " 17,\n",
+ " 20,\n",
+ " 12,\n",
+ " 16,\n",
+ " 21,\n",
+ " 9,\n",
+ " 19,\n",
+ " 23,\n",
+ " 4,\n",
+ " 11,\n",
+ " 19,\n",
+ " 5,\n",
+ " 14,\n",
+ " 21,\n",
+ " 6,\n",
+ " 0,\n",
+ " 22,\n",
+ " 3,\n",
+ " 0,\n",
+ " 4,\n",
+ " 4,\n",
+ " 21,\n",
+ " 11,\n",
+ " 11,\n",
+ " 6,\n",
+ " 17,\n",
+ " 19,\n",
+ " 23,\n",
+ " 8,\n",
+ " 1,\n",
+ " 6,\n",
+ " 19,\n",
+ " 8,\n",
+ " 1,\n",
+ " 4,\n",
+ " 21,\n",
+ " 12,\n",
+ " 15,\n",
+ " 18,\n",
+ " 0,\n",
+ " 0,\n",
+ " 19,\n",
+ " 4,\n",
+ " 14,\n",
+ " 0,\n",
+ " 18,\n",
+ " 4,\n",
+ " 21,\n",
+ " 0,\n",
+ " 4,\n",
+ " 24,\n",
+ " 16,\n",
+ " 14,\n",
+ " 7,\n",
+ " 0,\n",
+ " 12,\n",
+ " 4,\n",
+ " 14,\n",
+ " 13,\n",
+ " 13,\n",
+ " 2,\n",
+ " 5,\n",
+ " 20,\n",
+ " 8,\n",
+ " 3,\n",
+ " 14,\n",
+ " 4,\n",
+ " 5,\n",
+ " 0,\n",
+ " 5,\n",
+ " 0,\n",
+ " 19,\n",
+ " 19,\n",
+ " 4,\n",
+ " 12,\n",
+ " 20,\n",
+ " 8,\n",
+ " 12,\n",
+ " 13,\n",
+ " 5,\n",
+ " 11,\n",
+ " 25,\n",
+ " 13,\n",
+ " 1,\n",
+ " 4,\n",
+ " 10,\n",
+ " 14,\n",
+ " 5,\n",
+ " 14,\n",
+ " 1,\n",
+ " 17,\n",
+ " 11,\n",
+ " 8,\n",
+ " 0,\n",
+ " 4,\n",
+ " 7,\n",
+ " 7,\n",
+ " 0,\n",
+ " 20,\n",
+ " 8,\n",
+ " 7,\n",
+ " 13,\n",
+ " 13,\n",
+ " 13,\n",
+ " 22,\n",
+ " 25,\n",
+ " 0,\n",
+ " 4,\n",
+ " 4,\n",
+ " 21,\n",
+ " 19,\n",
+ " 11,\n",
+ " 11,\n",
+ " 19,\n",
+ " 15,\n",
+ " 0,\n",
+ " 0,\n",
+ " 11,\n",
+ " 13,\n",
+ " 0,\n",
+ " 13,\n",
+ " 21,\n",
+ " 19,\n",
+ " 25,\n",
+ " 11,\n",
+ " 25,\n",
+ " 20,\n",
+ " 20,\n",
+ " 2,\n",
+ " 15,\n",
+ " 19,\n",
+ " 0,\n",
+ " 4,\n",
+ " 11,\n",
+ " 8,\n",
+ " 13,\n",
+ " 0,\n",
+ " 13,\n",
+ " 15,\n",
+ " 0,\n",
+ " 0,\n",
+ " 7,\n",
+ " 4,\n",
+ " 22,\n",
+ " 5,\n",
+ " 19,\n",
+ " 7,\n",
+ " 0,\n",
+ " 14,\n",
+ " 18,\n",
+ " 4,\n",
+ " 19,\n",
+ " 0,\n",
+ " 17,\n",
+ " 8,\n",
+ " 1,\n",
+ " 13,\n",
+ " 1,\n",
+ " 13,\n",
+ " 21,\n",
+ " 7,\n",
+ " 0,\n",
+ " 4,\n",
+ " 21,\n",
+ " 3,\n",
+ " 7,\n",
+ " 24,\n",
+ " 24,\n",
+ " 19,\n",
+ " 11,\n",
+ " 12,\n",
+ " 20,\n",
+ " 23,\n",
+ " 1]"
+ ]
+ }
+ ],
+ "prompt_number": 17
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "m = np.matrix([[7,8], [11,11]])\n",
+ "m"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 106,
+ "text": [
+ "matrix([[ 7, 8],\n",
+ " [11, 11]])"
+ ]
+ }
+ ],
+ "prompt_number": 106
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "np.linalg.det(m)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 107,
+ "text": [
+ "-11.000000000000002"
+ ]
+ }
+ ],
+ "prompt_number": 107
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "m.I"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 108,
+ "text": [
+ "matrix([[-1. , 0.72727273],\n",
+ " [ 1. , -0.63636364]])"
+ ]
+ }
+ ],
+ "prompt_number": 108
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "v = np.matrix([[7], [22]])\n",
+ "v"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 37,
+ "text": [
+ "matrix([[ 7],\n",
+ " [22]])"
+ ]
+ }
+ ],
+ "prompt_number": 37
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "c = (m*v) % 26\n",
+ "c"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 46,
+ "text": [
+ "matrix([[9],\n",
+ " [5]])"
+ ]
+ }
+ ],
+ "prompt_number": 46
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "np.linalg.solve(m, c) % 26"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 48,
+ "text": [
+ "matrix([[ 7.],\n",
+ " [ 22.]])"
+ ]
+ }
+ ],
+ "prompt_number": 48
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "m*v"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 40,
+ "text": [
+ "matrix([[ 87],\n",
+ " [109]])"
+ ]
+ }
+ ],
+ "prompt_number": 40
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "(m*v)%26"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 41,
+ "text": [
+ "matrix([[9],\n",
+ " [5]])"
+ ]
+ }
+ ],
+ "prompt_number": 41
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "np.linalg.solve(m, (m*v)%26)%26"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 42,
+ "text": [
+ "matrix([[ 7.],\n",
+ " [ 22.]])"
+ ]
+ }
+ ],
+ "prompt_number": 42
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "len(m)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 51,
+ "text": [
+ "2"
+ ]
+ }
+ ],
+ "prompt_number": 51
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def hill_encipher(matrix, message_letters, fillvalue='a'):\n",
+ " n = len(matrix)\n",
+ " sanitised_message = sanitise(message_letters)\n",
+ " if len(sanitised_message) % n != 0:\n",
+ " padding = fillvalue[0] * (n - len(sanitised_message) % n)\n",
+ " else:\n",
+ " padding = ''\n",
+ " message = [ord(c) - ord('a') for c in sanitised_message + padding]\n",
+ " message_chunks = [message[i:i+n] for i in range(0, len(message), n)]\n",
+ " # message_chunks = chunks(message, len(matrix), fillvalue=None)\n",
+ " enciphered_chunks = [((matrix * np.matrix(c).T).T).tolist()[0] for c in message_chunks]\n",
+ " return ''.join([chr(int(round(l)) % 26 + ord('a')) for l in sum(enciphered_chunks, [])])"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 181
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_encipher(m, 'hellothere')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 156,
+ "text": [
+ "'drjiqzdrvx'"
+ ]
+ }
+ ],
+ "prompt_number": 156
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "msg = [ord(c) - ord('a') for c in 'hellothere']\n",
+ "msg"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 68,
+ "text": [
+ "[7, 4, 11, 11, 14, 19, 7, 4, 17, 4]"
+ ]
+ }
+ ],
+ "prompt_number": 68
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
+ "msgc"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 112,
+ "text": [
+ "[[7, 11], [14, 25], [21, 14], [7, 11], [11, 15], [0, 0]]"
+ ]
+ }
+ ],
+ "prompt_number": 112
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "((m*np.matrix(msgc[0]).T).T % 26).tolist()[0]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 87,
+ "text": [
+ "[7, 11]"
+ ]
+ }
+ ],
+ "prompt_number": 87
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def hill_decipher(matrix, message, fillvalue='a'):\n",
+ " adjugate = linalg.det(matrix)*linalg.inv(matrix)\n",
+ " inverse_determinant = modular_division_table[int(round(linalg.det(matrix))) % 26][1]\n",
+ " inverse_matrix = (inverse_determinant * adjugate) % 26\n",
+ " return hill_encipher(inverse_matrix, message, fillvalue) "
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 195
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_decipher(m, 'drjiqzdrvx')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 161,
+ "text": [
+ "'hellothere'"
+ ]
+ }
+ ],
+ "prompt_number": 161
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "msg = [ord(c) - ord('a') for c in 'drjiqzdrvxaa']\n",
+ "msg"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 114,
+ "text": [
+ "[3, 17, 9, 8, 16, 25, 3, 17, 21, 23, 0, 0]"
+ ]
+ }
+ ],
+ "prompt_number": 114
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
+ "msgc"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 115,
+ "text": [
+ "[[3, 17], [9, 8], [16, 25], [3, 17], [21, 23], [0, 0]]"
+ ]
+ }
+ ],
+ "prompt_number": 115
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "(np.linalg.solve(m, np.matrix(msgc[0]).T).T % 26)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 116,
+ "text": [
+ "matrix([[ 9.36363636, 18.18181818]])"
+ ]
+ }
+ ],
+ "prompt_number": 116
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "m_adj = linalg.det(m)*linalg.inv(m)\n",
+ "m_adj"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 142,
+ "text": [
+ "matrix([[ 11., -8.],\n",
+ " [-11., 7.]])"
+ ]
+ }
+ ],
+ "prompt_number": 142
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "modular_division_table[int(round(linalg.det(m))) % 26][1]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 148,
+ "text": [
+ "7"
+ ]
+ }
+ ],
+ "prompt_number": 148
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "m_inv = (modular_division_table[int(round(linalg.det(m))) % 26][1] * m_adj) % 26\n",
+ "m_inv"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 150,
+ "text": [
+ "matrix([[ 25., 22.],\n",
+ " [ 1., 23.]])"
+ ]
+ }
+ ],
+ "prompt_number": 150
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_encipher(m_inv, 'drjiqzdrvx')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 157,
+ "text": [
+ "'hellothere'"
+ ]
+ }
+ ],
+ "prompt_number": 157
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "np.dot(m , 1/linalg.det(m) * mc)"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 120,
+ "text": [
+ "matrix([[ 1., 0.],\n",
+ " [ 0., 1.]])"
+ ]
+ }
+ ],
+ "prompt_number": 120
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "ml = np.matrix([[6, 24, 1], [13, 16, 10], [20, 17, 15]])\n",
+ "ml"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 122,
+ "text": [
+ "matrix([[ 6, 24, 1],\n",
+ " [13, 16, 10],\n",
+ " [20, 17, 15]])"
+ ]
+ }
+ ],
+ "prompt_number": 122
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "ml_adj = linalg.det(ml)*linalg.inv(ml) % 26\n",
+ "ml_adj"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 137,
+ "text": [
+ "matrix([[ 18., 21., 16.],\n",
+ " [ 5., 18., 5.],\n",
+ " [ 5., 14., 18.]])"
+ ]
+ }
+ ],
+ "prompt_number": 137
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "modular_division_table[int(linalg.det(ml) % 26)][1]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 138,
+ "text": [
+ "25"
+ ]
+ }
+ ],
+ "prompt_number": 138
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "ml_inv = (modular_division_table[int(linalg.det(ml) % 26)][1] * ml_adj) % 26\n",
+ "ml_inv"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 139,
+ "text": [
+ "matrix([[ 8., 5., 10.],\n",
+ " [ 21., 8., 21.],\n",
+ " [ 21., 12., 8.]])"
+ ]
+ }
+ ],
+ "prompt_number": 139
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_encipher(ml, 'hello there')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 193,
+ "text": [
+ "'tfjflpznvyac'"
+ ]
+ }
+ ],
+ "prompt_number": 193
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_decipher(ml, 'tfjflpznvyac')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 196,
+ "text": [
+ "'hellothereaa'"
+ ]
+ }
+ ],
+ "prompt_number": 196
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_encipher(ml, 'act')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 182,
+ "text": [
+ "'poh'"
+ ]
+ }
+ ],
+ "prompt_number": 182
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_decipher(ml, 'poh')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "stream": "stdout",
+ "text": [
+ "[[ 8. 5. 10.]\n",
+ " [ 21. 8. 21.]\n",
+ " [ 21. 12. 8.]]\n"
+ ]
+ },
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 192,
+ "text": [
+ "'act'"
+ ]
+ }
+ ],
+ "prompt_number": 192
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "[chr(int(round(i)) % 26 + ord('a')) for i in (ml_inv * np.matrix([ord(c) - ord('a') for c in 'poh']).T).T.tolist()[0]]"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 180,
+ "text": [
+ "['a', 'c', 't']"
+ ]
+ }
+ ],
+ "prompt_number": 180
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "hill_encipher(ml_inv, 'poh')"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [
+ {
+ "metadata": {},
+ "output_type": "pyout",
+ "prompt_number": 184,
+ "text": [
+ "'act'"
+ ]
+ }
+ ],
+ "prompt_number": 184
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [],
+ "language": "python",
+ "metadata": {},
+ "outputs": []
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
\ No newline at end of file