From: Neil Smith Date: Sun, 30 Nov 2014 12:32:39 +0000 (+0000) Subject: Hill ciphers enciphering and deciphering done X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=cb023a39e779de938dc6a3aac3273e26f9a2ab83;p=cipher-training.git Hill ciphers enciphering and deciphering done --- diff --git a/cipher.py b/cipher.py index 6cce725..cd75d2c 100644 --- a/cipher.py +++ b/cipher.py @@ -3,6 +3,9 @@ import collections 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 * @@ -630,6 +633,44 @@ def railfence_decipher(message, height, fillvalue=''): 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, diff --git a/hill-ciphers.ipynb b/hill-ciphers.ipynb new file mode 100644 index 0000000..909828a --- /dev/null +++ b/hill-ciphers.ipynb @@ -0,0 +1,1392 @@ +{ + "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