+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "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 multiprocessing import Pool\n",
+ "\n",
+ "\n",
+ "from cipher import *\n",
+ "from cipherbreak import *\n",
+ "\n",
+ "c7b = open('2016/7b.ciphertext').read()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 108,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "c7bs = sanitise(c7b)\n",
+ "c7br = cat(reversed(c7bs))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bifid_grid(keyword, wrap_alphabet, letter_mapping):\n",
+ " cipher_alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet)\n",
+ " if letter_mapping is None:\n",
+ " letter_mapping = {'j': 'i'}\n",
+ " translation = ''.maketrans(letter_mapping)\n",
+ " cipher_alphabet = cat(collections.OrderedDict.fromkeys(cipher_alphabet.translate(translation)))\n",
+ " f_grid = {k: ((i // 5) + 1, (i % 5) + 1) \n",
+ " for i, k in enumerate(cipher_alphabet)}\n",
+ " r_grid = {((i // 5) + 1, (i % 5) + 1): k \n",
+ " for i, k in enumerate(cipher_alphabet)}\n",
+ " return translation, f_grid, r_grid"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 156,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import pprint"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 157,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "({106: 'i'},\n",
+ " {'a': (1, 4),\n",
+ " 'b': (2, 1),\n",
+ " 'c': (2, 2),\n",
+ " 'd': (2, 3),\n",
+ " 'e': (2, 4),\n",
+ " 'f': (2, 5),\n",
+ " 'g': (1, 2),\n",
+ " 'h': (3, 1),\n",
+ " 'i': (1, 1),\n",
+ " 'k': (3, 2),\n",
+ " 'l': (3, 3),\n",
+ " 'm': (3, 4),\n",
+ " 'n': (1, 5),\n",
+ " 'o': (3, 5),\n",
+ " 'p': (4, 1),\n",
+ " 'q': (4, 2),\n",
+ " 'r': (4, 3),\n",
+ " 's': (4, 4),\n",
+ " 't': (4, 5),\n",
+ " 'u': (1, 3),\n",
+ " 'v': (5, 1),\n",
+ " 'w': (5, 2),\n",
+ " 'x': (5, 3),\n",
+ " 'y': (5, 4),\n",
+ " 'z': (5, 5)},\n",
+ " {(1, 1): 'i',\n",
+ " (1, 2): 'g',\n",
+ " (1, 3): 'u',\n",
+ " (1, 4): 'a',\n",
+ " (1, 5): 'n',\n",
+ " (2, 1): 'b',\n",
+ " (2, 2): 'c',\n",
+ " (2, 3): 'd',\n",
+ " (2, 4): 'e',\n",
+ " (2, 5): 'f',\n",
+ " (3, 1): 'h',\n",
+ " (3, 2): 'k',\n",
+ " (3, 3): 'l',\n",
+ " (3, 4): 'm',\n",
+ " (3, 5): 'o',\n",
+ " (4, 1): 'p',\n",
+ " (4, 2): 'q',\n",
+ " (4, 3): 'r',\n",
+ " (4, 4): 's',\n",
+ " (4, 5): 't',\n",
+ " (5, 1): 'v',\n",
+ " (5, 2): 'w',\n",
+ " (5, 3): 'x',\n",
+ " (5, 4): 'y',\n",
+ " (5, 5): 'z'})\n"
+ ]
+ }
+ ],
+ "source": [
+ "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, None))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 158,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "({106: 'i'},\n",
+ " {'a': (1, 2),\n",
+ " 'b': (1, 3),\n",
+ " 'c': (1, 4),\n",
+ " 'd': (1, 5),\n",
+ " 'e': (2, 1),\n",
+ " 'f': (2, 2),\n",
+ " 'g': (2, 3),\n",
+ " 'h': (2, 4),\n",
+ " 'i': (2, 5),\n",
+ " 'k': (3, 1),\n",
+ " 'l': (3, 2),\n",
+ " 'm': (3, 3),\n",
+ " 'n': (3, 4),\n",
+ " 'o': (3, 5),\n",
+ " 'p': (4, 1),\n",
+ " 'q': (4, 2),\n",
+ " 'r': (4, 3),\n",
+ " 's': (4, 4),\n",
+ " 't': (4, 5),\n",
+ " 'u': (5, 1),\n",
+ " 'v': (5, 2),\n",
+ " 'w': (5, 3),\n",
+ " 'x': (5, 4),\n",
+ " 'y': (5, 5),\n",
+ " 'z': (1, 1)},\n",
+ " {(1, 1): 'z',\n",
+ " (1, 2): 'a',\n",
+ " (1, 3): 'b',\n",
+ " (1, 4): 'c',\n",
+ " (1, 5): 'd',\n",
+ " (2, 1): 'e',\n",
+ " (2, 2): 'f',\n",
+ " (2, 3): 'g',\n",
+ " (2, 4): 'h',\n",
+ " (2, 5): 'i',\n",
+ " (3, 1): 'k',\n",
+ " (3, 2): 'l',\n",
+ " (3, 3): 'm',\n",
+ " (3, 4): 'n',\n",
+ " (3, 5): 'o',\n",
+ " (4, 1): 'p',\n",
+ " (4, 2): 'q',\n",
+ " (4, 3): 'r',\n",
+ " (4, 4): 's',\n",
+ " (4, 5): 't',\n",
+ " (5, 1): 'u',\n",
+ " (5, 2): 'v',\n",
+ " (5, 3): 'w',\n",
+ " (5, 4): 'x',\n",
+ " (5, 5): 'y'})\n"
+ ]
+ }
+ ],
+ "source": [
+ "pprint.pprint(bifid_grid('z', KeywordWrapAlphabet.from_a, None))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 159,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "({113: 'p'},\n",
+ " {'a': (1, 4),\n",
+ " 'b': (2, 1),\n",
+ " 'c': (2, 2),\n",
+ " 'd': (2, 3),\n",
+ " 'e': (2, 4),\n",
+ " 'f': (2, 5),\n",
+ " 'g': (1, 2),\n",
+ " 'h': (3, 1),\n",
+ " 'i': (1, 1),\n",
+ " 'j': (3, 2),\n",
+ " 'k': (3, 3),\n",
+ " 'l': (3, 4),\n",
+ " 'm': (3, 5),\n",
+ " 'n': (1, 5),\n",
+ " 'o': (4, 1),\n",
+ " 'p': (4, 2),\n",
+ " 'r': (4, 3),\n",
+ " 's': (4, 4),\n",
+ " 't': (4, 5),\n",
+ " 'u': (1, 3),\n",
+ " 'v': (5, 1),\n",
+ " 'w': (5, 2),\n",
+ " 'x': (5, 3),\n",
+ " 'y': (5, 4),\n",
+ " 'z': (5, 5)},\n",
+ " {(1, 1): 'i',\n",
+ " (1, 2): 'g',\n",
+ " (1, 3): 'u',\n",
+ " (1, 4): 'a',\n",
+ " (1, 5): 'n',\n",
+ " (2, 1): 'b',\n",
+ " (2, 2): 'c',\n",
+ " (2, 3): 'd',\n",
+ " (2, 4): 'e',\n",
+ " (2, 5): 'f',\n",
+ " (3, 1): 'h',\n",
+ " (3, 2): 'j',\n",
+ " (3, 3): 'k',\n",
+ " (3, 4): 'l',\n",
+ " (3, 5): 'm',\n",
+ " (4, 1): 'o',\n",
+ " (4, 2): 'p',\n",
+ " (4, 3): 'r',\n",
+ " (4, 4): 's',\n",
+ " (4, 5): 't',\n",
+ " (5, 1): 'v',\n",
+ " (5, 2): 'w',\n",
+ " (5, 3): 'x',\n",
+ " (5, 4): 'y',\n",
+ " (5, 5): 'z'})\n"
+ ]
+ }
+ ],
+ "source": [
+ "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, {'q': 'p'}))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "# def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
+ "# letter_mapping=None, period=None):\n",
+ "# translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
+ " \n",
+ "# t_message = message.translate(translation)\n",
+ "# pairs0 = [f_grid[l] for l in t_message]\n",
+ "# items = sum([list(p) for p in pairs0], [])\n",
+ "# gap = len(message)\n",
+ "# pairs1 = [(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]\n",
+ "# return cat(r_grid[p] for p in pairs1)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 162,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "def bifid_encipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
+ " letter_mapping=None, period=None, fillvalue=None):\n",
+ " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
+ " \n",
+ " t_message = message.translate(translation)\n",
+ " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
+ " if period:\n",
+ " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
+ " if len(chunked_pairs[-1]) < period and fillvalue:\n",
+ " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
+ " else:\n",
+ " chunked_pairs = [pairs0]\n",
+ " \n",
+ " pairs1 = []\n",
+ " for c in chunked_pairs:\n",
+ " items = sum(list(list(i) for i in zip(*c)), [])\n",
+ " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
+ " pairs1 += p\n",
+ " \n",
+ " return cat(r_grid[p] for p in pairs1)\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 163,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'nkklawamdkoedysipdesltirsnoesqlvvaloderbhel'"
+ ]
+ },
+ "execution_count": 163,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_encipher('this is a test message for the keyword decipherment', 'elephant', wrap_alphabet=KeywordWrapAlphabet.from_last)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "ot, ofg, org = bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(1, 1),\n",
+ " (1, 5),\n",
+ " (2, 3),\n",
+ " (1, 1),\n",
+ " (1, 4),\n",
+ " (2, 2),\n",
+ " (1, 3),\n",
+ " (4, 3),\n",
+ " (4, 3),\n",
+ " (5, 4)]"
+ ]
+ },
+ "execution_count": 85,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "op0 = [ofg[l] for l in \"indiacurry\"]\n",
+ "op0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[[(1, 1), (1, 5), (2, 3), (1, 1)],\n",
+ " [(1, 4), (2, 2), (1, 3), (4, 3)],\n",
+ " [(4, 3), (5, 4), (1, 4), (1, 4)]]"
+ ]
+ },
+ "execution_count": 86,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ocp = chunks(op0, 4, fillvalue=[[ofg['a']]])\n",
+ "acc = []\n",
+ "ocp"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(1, 1),\n",
+ " (2, 1),\n",
+ " (1, 5),\n",
+ " (3, 1),\n",
+ " (1, 2),\n",
+ " (1, 4),\n",
+ " (4, 2),\n",
+ " (3, 3),\n",
+ " (4, 5),\n",
+ " (1, 1),\n",
+ " (3, 4),\n",
+ " (4, 4)]"
+ ]
+ },
+ "execution_count": 87,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "acc=[]\n",
+ "for c in ocp:\n",
+ " items = sum(list(list(i) for i in zip(*c)), [])\n",
+ " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
+ " acc += p\n",
+ "acc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ibnhgaqltims'"
+ ]
+ },
+ "execution_count": 88,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "cat(org[p] for p in acc)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 164,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
+ " letter_mapping=None, period=None, fillvalue=None):\n",
+ " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
+ " \n",
+ " t_message = message.translate(translation)\n",
+ " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
+ " if period:\n",
+ " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
+ " if len(chunked_pairs[-1]) < period and fillvalue:\n",
+ " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
+ " else:\n",
+ " chunked_pairs = [pairs0]\n",
+ " \n",
+ " pairs1 = []\n",
+ " for c in chunked_pairs:\n",
+ " items = [j for i in c for j in i]\n",
+ " gap = len(c)\n",
+ " p = [(items[i], items[i+gap]) for i in range(gap)]\n",
+ " pairs1 += p\n",
+ "\n",
+ " return cat(r_grid[p] for p in pairs1) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "({106: 'i'},\n",
+ " {'a': (1, 4),\n",
+ " 'b': (2, 1),\n",
+ " 'c': (2, 2),\n",
+ " 'd': (2, 3),\n",
+ " 'e': (2, 4),\n",
+ " 'f': (2, 5),\n",
+ " 'g': (1, 2),\n",
+ " 'h': (3, 1),\n",
+ " 'i': (1, 1),\n",
+ " 'k': (3, 2),\n",
+ " 'l': (3, 3),\n",
+ " 'm': (3, 4),\n",
+ " 'n': (1, 5),\n",
+ " 'o': (3, 5),\n",
+ " 'p': (4, 1),\n",
+ " 'q': (4, 2),\n",
+ " 'r': (4, 3),\n",
+ " 's': (4, 4),\n",
+ " 't': (4, 5),\n",
+ " 'u': (1, 3),\n",
+ " 'v': (5, 1),\n",
+ " 'w': (5, 2),\n",
+ " 'x': (5, 3),\n",
+ " 'y': (5, 4),\n",
+ " 'z': (5, 5)},\n",
+ " {(1, 1): 'i',\n",
+ " (1, 2): 'g',\n",
+ " (1, 3): 'u',\n",
+ " (1, 4): 'a',\n",
+ " (1, 5): 'n',\n",
+ " (2, 1): 'b',\n",
+ " (2, 2): 'c',\n",
+ " (2, 3): 'd',\n",
+ " (2, 4): 'e',\n",
+ " (2, 5): 'f',\n",
+ " (3, 1): 'h',\n",
+ " (3, 2): 'k',\n",
+ " (3, 3): 'l',\n",
+ " (3, 4): 'm',\n",
+ " (3, 5): 'o',\n",
+ " (4, 1): 'p',\n",
+ " (4, 2): 'q',\n",
+ " (4, 3): 'r',\n",
+ " (4, 4): 's',\n",
+ " (4, 5): 't',\n",
+ " (5, 1): 'v',\n",
+ " (5, 2): 'w',\n",
+ " (5, 3): 'x',\n",
+ " (5, 4): 'y',\n",
+ " (5, 5): 'z'})"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 139,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ibidonhprm'"
+ ]
+ },
+ "execution_count": 139,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_encipher(\"indiajelly\", 'iguana')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 140,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'indiaielly'"
+ ]
+ },
+ "execution_count": 140,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher('ibidonhprm', 'iguana')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 137,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ibnhgaqltm'"
+ ]
+ },
+ "execution_count": 137,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_encipher(\"indiacurry\", 'iguana', period=4)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 138,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'indiacurry'"
+ ]
+ },
+ "execution_count": 138,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher(\"ibnhgaqltm\", 'iguana', period=4)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 144,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ibnhgaqltzml'"
+ ]
+ },
+ "execution_count": 144,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_encipher(\"indiacurry\", 'iguana', period=4, fillvalue='x')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 146,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'indiacurryxx'"
+ ]
+ },
+ "execution_count": 146,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher(\"ibnhgaqltzml\", 'iguana', period=4)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 101,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "p0 = [(1, 1), (2, 1), (1, 5), (3, 1)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 103,
+ "metadata": {
+ "collapsed": false,
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1, 1, 2, 1, 1, 5, 3, 1]"
+ ]
+ },
+ "execution_count": 103,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "t0 = [j for i in p0 for j in i]\n",
+ "t0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 104,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(1, 1), (1, 5), (2, 3), (1, 1)]"
+ ]
+ },
+ "execution_count": 104,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[(t0[i], t0[i+4]) for i in range(4)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 130,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'martinwehavemadeadreadfulmistakeandihavebeentooslowtoadmitthattomyselfihavehadavisitfromthewomanfromthesyndicateandiconfrontedheraboutthesourceofthetemplatessheconfirmedmyworstfearsandnowiwanttocrawlawayanddiewhathavewedoneoursoftwarehasledtosomuchsufferingwhenitwasdesignedtodotheoppositeiaskedherhowthecabinetofficecouldpossiblyhaveauthorisedthisandshelaughedandexplainedthatthesyndicatenolongerworkedforthebritishgovernmentcallitprivateenterpriseshesaidwehavealwaysbeengoodatthatmyhorrormusthavebeenwrittenallovermyfaceshedidntseemsurprisedatmyreactionbutequallyshedidnttakeitwellandcivilitywasabandonediaskedherhowitcouldbelegalletalonemoraltodowhattheyproposedandheranswerwasthatitwasnecessaryisaidwewouldnthelpthemandshesaiditwasnecessarythatwedidisaidiwouldntbeabletofacemyfamilyandfriendsifwecooperatedandshesaidiwouldnthavetoworryaboutthatforlongonewayoranotherthepdssyndicateweregoingtomakesurewebothdisappearedlookingbackicanseethatfromthestartthiswholethinghasactedtodrawusintoitscentreandnowiamattheeventhorizonalmostunabletoescapeitspullbutithinkwehaveonelastchanceiamsureshewillbevisitingyouaswellshethinkswehavenochoicebutithinkachoiceisallwehavewhateveryoudoholdoutforbettertermsshehastobelievethatyouareonsideandmotivatedbygreedsothatshewontworryaboutanyqualmsyoumighthaveconvinceherthatyouwillconvincemetocooperatetellherthatyouthinkyoushouldworkfromthecollectiveinosloandthatyouwantpaymentviathebankinswitzerlandigottheimpressionthatmoneyisnotaproblemwithmoneyinaswissbankandtheexpertiseandconnectivityaffordedbythecollectiveithinkwehaveachancetoescapeandtotrytostopthemperhapswewillsurvivethisperhapswecanbringthemdown'"
+ ]
+ },
+ "execution_count": 130,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4, fillvalue=None)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 147,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'martin we have made a dreadful mistake and i have been too slow to admit that to myself i have had a visit from the woman from the syndicate and i confronted her about the source of the templates she confirmed my worst fears and now i want to crawl away and die what have we done our software has led to so much suffering when it was designed to do the opposite i asked her how the cabinet office could possibly have authorised this and she laughed and explained that the syndicate no longer worked for the british government call it private enterprises he said we have always been good at that my horror must have been written all over myfaces he didnt seem surprised at my reaction but equally she didnt take it well and civility was abandoned i asked her how it could be legal let alone moral to do what they proposed and her answer was that it was necessary i said we wouldnt help them and she said it was necessary that we did i said i wouldnt be able to face my family and friends if we cooperated and she said i wouldnt have to worry about that for long one way or another the pds syndicate were going to make sure we both disappeared looking back i can see that from the start this whole thing has acted to draw us into its centre and now i am at the event horizon almost unable to escape its pull but i think we have one last chance i am sure she will be visiting you as well she thinks we have no choice but i think a choice is all we have whatever you do hold out for better terms she has to believe that you are on side and motivated by greed so that she wont worry about any qualms you might have convince her that you will convince me to cooperate tell her that you think you should work from the collective in oslo and that you want payment via the bank in switzerland i got the impression that money is not a problem with money in a swiss bank and the expertise and connectivity afforded by the collective i think we have a chance to escape and to try to stop them perhaps we will survive this perhaps we can bring them down'"
+ ]
+ },
+ "execution_count": 147,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "wcat(segment(bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "p0 = [(2, 1), (3, 3), (3, 3), (5, 1), (1, 4)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2, 1, 3, 3, 3, 3, 5, 1, 1, 4]"
+ ]
+ },
+ "execution_count": 54,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "items = sum([list(p) for p in p0], [])\n",
+ "items"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(2, 3), (1, 5), (3, 1), (3, 1), (3, 4)]"
+ ]
+ },
+ "execution_count": 55,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "gap=5\n",
+ "[(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "c7bs = sanitise(c7b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 115,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bifid_break_mp(message, wordlist=keywords, fitness=Pletters,\n",
+ " number_of_solutions=1, chunksize=500):\n",
+ " \"\"\"Breaks a keyword substitution cipher using a dictionary and\n",
+ " frequency analysis\n",
+ "\n",
+ " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
+ " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
+ " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
+ " (('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...)\n",
+ " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
+ " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
+ " wordlist=['cat', 'elephant', 'kangaroo'], \\\n",
+ " number_of_solutions=2) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n",
+ " [(('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...), \n",
+ " (('elephant', <KeywordWrapAlphabet.from_largest: 3>), -52.834575011...)]\n",
+ " \"\"\"\n",
+ " with Pool() as pool:\n",
+ " helper_args = [(message, word, wrap, fitness)\n",
+ " for word in wordlist\n",
+ " for wrap in KeywordWrapAlphabet]\n",
+ " # Gotcha: the helper function here needs to be defined at the top level\n",
+ " # (limitation of Pool.starmap)\n",
+ " breaks = pool.starmap(bifid_break_worker, helper_args, chunksize)\n",
+ " if number_of_solutions == 1:\n",
+ " return max(breaks, key=lambda k: k[1])\n",
+ " else:\n",
+ " return sorted(breaks, key=lambda k: k[1], reverse=True)[:number_of_solutions]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 116,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bifid_break_worker(message, keyword, wrap_alphabet, fitness):\n",
+ " plaintext = bifid_decipher(message, keyword, wrap_alphabet)\n",
+ " fit = fitness(plaintext)\n",
+ " logger.debug('Keyword break attempt using key {0} (wrap={1}) gives fit of '\n",
+ " '{2} and decrypt starting: {3}'.format(keyword, \n",
+ " wrap_alphabet, fit, sanitise(plaintext)[:50]))\n",
+ " return (keyword, wrap_alphabet), fit"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 107,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'enamokkneogiyegrkcuzbgsydkoqoswiwvtgbolrkfuzbgsyskdqusgnttqetuonyegyfkbsteqeycgbudbvqadcepgqrsbbeaeoqilrqcsosfcdyrbztiuirvqrtcmesbkudboeytksofknyegrambmctvxeogttfggemokopiqwinutqhdtoftsgsathnemlteprmrqbstdolsaklrueucsvncyhgqqcsfqlutsdxzthnfuvotauhnyegosloeogwrrqclelbonknefqkrkofvoqhxttvrimhyttvyqosrlegqtbeyroeuegbtnqkeecgqepblclvutouaehtoekceqgpeobwaohndxlstmvnvalttupquvoieruortugrhfsyqosnsqcesrvhtcrarvqnshkudbistnbwuootauhtqefiolctxqoqhdsmrneettrtberyybtnqblqxgrtrveqyfoboxwaehwlplqrcbiowhirimheyotqcciorhitvdaqkdurimhtheslelwxuooneagedooqlfibrlfhesrpxtgrrbkarhrxqobtogwaehwrimheyotlviqpesoyfkbsteqoviiynstnvhltfgarqostqdfotktpfhlrnadyegrtencsrtltknqffyqsnietwrixhogeqgsooihkiuhtwtonotknenquarhtnerycgicadbschhthlbeurbzpmqkqbsoebweprtepkhtsqhrslbrrefycoisnkumuedqrseqtshftqvftvkntlgbyqbyqosyotbucvtetvqoawhtgniucoadpiqomkeysgcyroeuegbefwimtedcpqcyogakzhbnepcztbqoviiotcnguiocdaipkqbkebwyqosepuqsrecnfsvedoipoqkmyegsqdsaogktgniurofkwfldeoupsqerncsfevoyqosxcoueswnfoqkspkbnyrheuqxotktarhasoiofnqhtokluoqivslbqhbcveqberoaboskskcsfslctsgkapbqftvuiilvcsbkaqlbrrubwtgtnkdboskylzlqqyetqekleuebrsyspnbrcfqspstdntrndsichescznbprqealulhteroctydoocwanhtprnocothnypoqysosniltodcsfyvvolwaehwdpiqoskedwonrtentycobwanelolftbnneksonwlhrsqcqqcqrsopeckrcountigqtldycoisnkuotktanhetwklvshfspkboxkqaolkmyegdqossdcorqoszoowaohabmityghiurocczicttqkifbboekyorhehedkxrobesooztmbqnsbtsqcnkgqnxcorruhokkaergezpctbpdnntqqshcqaehrfyvenwqtttbgsrcfvqasarhfksbkufvvawlacteqtfnvctvhspkqwyocnrtormzdnckouekbomkttarlptmroyketcbrusoeqystofbqoskctenquekbkybgtfrbktbxsqesswgeysggrqfsswgeedoovxaiqvdabaginnrptyqoqesomudleoylstoqtodcoawhkybgeukqdgogzxeiexrinpchoawheewgepth'"
+ ]
+ },
+ "execution_count": 107,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "c7bs = sanitise(c7b)\n",
+ "c7br = cat(reversed(c7bs))\n",
+ "c7br"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 148,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(('ligo', <KeywordWrapAlphabet.from_a: 1>), -2505.924490942904)"
+ ]
+ },
+ "execution_count": 148,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_break_mp(c7bs, wordlist=['gravity', 'ligo'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 102,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'ksotagstmczesqstldwfasoehepicltaryruvgstiwbtylwzlanehrdmthhlqzeohpsdytllgdxfcetbiislqetoukobnterkoyonsetkodhtymxuefpdtnhnsulwnnurhiotctcrwhprbssrdblxanlrxadxgxatetsegdoeuhawberbaswolpqkrkpfcxufohcyefaeabqtkbrykbdonghsbaodvongcfdvngmeslhetnytkocenotirklsatenkdeeyoentbryuoleqoefcuxpqbsirotbogkvtqbrqgyoqamkninrfottolgmynbsekmeouwueklcpqrekyylvronsntcotrrctdvoyfthkgalscldypooicxrtpdyttohfoqtprrbgtwepsycwpswuylkedbiglsylbctcfecisumvrbyparteagabdqouuttohvbtcdtxczusxrtleburbtkapmsfctmokootcoibkclbetoaralxzdnlpanenadkhhgtsldnyrupnqsravhtpohmplgtaacuhfpttdebroaqhedgvooyyneoebrfudfodroyklhsheqheeqhdinusytmhdqqedsbbdzcylgukonttacivvvcrprteautwrxhdmczntnixhzbeasmboscsyeqdtsxxeiodohrnofaidlbabrobumelkaeuvnlylglqnfpeqklhwlqeselhameievlbeawrlnllyetoeolencrduoghqqoeqyhlqidrrvndrrwnfhmottqllpayunortyoeariuhharstrhnsfaaoqlipqkohcrnldicnlshnysnrtdbiggeonatcseqosygonehtdutacbzdbstdcrzttntrbtunrotcuewfslftkgdruetlrxrgbmvegfsqieybgqtfxaxrvqbybcaibhoeoolnpxnrdatsspxotloerkwotcheutoerrufnprncktohsqarexdccnbtbekxtqtcrtbaqsottmbltovlurbeoolrtpksbtpyvrasrbtkfricyeremtpaqunucemnterrmdpoldyaicofeoppgepxtdaioeesqqysthohkeotktnstxntgtmhqvyhoythkeanebdshlmtrnqhrunweeeozctiofegqolrfmmdbdacryrmqrypwuwvcntdyqksdamrsglgisanncrmoerfveprpkgbagkerobderbnbatdnedugenxarredlduheegqbrycawnknbnylomloetokdolqreyuecvufbrpsmsptadqthkuotdvknhuyetldctwotidfglrgspmhokusbvtpvbeietnxqbirwhspqetmyotewabodyfppaoacoequgsrrgtyqfsnegmtfvzelmfwosrutwpvnamanthhgcnepsepeguldrhaenwolwhhohnsrlpxnsdhenvadcbyqicaboptfaoknvcmeoerqbtlyovbbddommednhlmrlcyaeflratepytylrnpcantuepwpxxanfthsdnowzirihfqqcedlewwhkcelinfwniiohclardlbqqokzrwvdswbufemcsqqveqnbruynipgrbaytsqkkkyodugayche'"
+ ]
+ },
+ "execution_count": 102,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher(c7bs, 'capris', KeywordWrapAlphabet.from_a )"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 104,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'dnrobchyoikvkwtucnsiganmyoanfatckweqpwxwehfdpoxqdvtworugsnpsxanmycvirrgedmuihpienwfnpwyzdffaqsxsoutvbvqlovoplenqrnktqlernruwptiswodnhaxomrtwbmpunnbnolcrvsasmcblsvawegytshecczeperucfeqlrcosbfdhdkcaeipnsligmsnapleqpoutoqgtcobyzorcehvvkkrhoxngkavnolkcrncshwetpocgnysxewemonekysintysuqrlntykpvsckgenbecfybfmycsrtzrxfckstgbirtnmnhdhcetfvuttwptpbigplyctfisoxttslhhbvtnotminnusfcqobdtnlhnpbnhxhpirckoatchwiaofaloprrbyonlouscekwlsnboyciswcoosyirodpwsgghcqhofeuosmtqfhqsztrsscwxfzwrnhhnphtpvwnurikaeoxgftoyodrmaqnosloukciskmbycicidsgeofsbrfodhsrtskwtpbtgnsmnyncrvsrhtwrsiolhlylrnntvrkenffvgfypknntxryqqgonspndmocrhcpfrnbgerwqncuiciqverfealtrnoomnwdnenepldpgatsbbffsaogoynownnotoxbeckllrnonbknycsensfleqbctonegzaccsifmnuezvlfqsurrgwviiuwrdcgoininoyseugowzkpntfctreowotnetkswlctahmgrpoypohsnoqnqooogboctspteznllttcurbcbiewnslipsshliwsybvalnlosrrtpcfzepwsnonktceovhhrnqfeilrkmsrlseoinyfsfunulffevuofwrenqbrettkrtkbnkelciibvsysafkrisombfmsqgwlfbnekikdyreipgzshnonclsrzgyceeanhlvcluucfsomraasehigprxbmfiftdnhgxhfbnzopntrsgcudoigstteflifktxiewbaqltwevuznctfgxhgtihgeruomubtgsvaxgoysnontudtebmabnbvsnsrqffslnigcfnemqgnhfckqpncoewfrnmbictedfkwaateghravmulprcftrqngazecectflxcicnhhwllbrwpoiitgqvknmogoeckpsqtvofttwbhpsntarshokvnigrlypropqiitoznlghoknmifdedtapmpisprrsfewfnqttitvnkoaltfmfqicnsaedyxuaklctantctroesoorbkkmpktnwnoulfnmrvougqstqkfdtttvarerhylgfoimeanomleupotornghfryklsyfgtnxdnnsttsoitriyisennougsveatellinkpetkaxodulaihaoebevagqodofghminllhpelcnszrbagvzsclxphrvplbhossnckahwaeroakctnekodiwgfinquogmgraqpgqafienectgnwoeusnilosiptysyfxuydrdxsgtcoucislntosflhttnogzrlntrwkrxiokklphbagvsufdlxpuhpnoqwuukirefqweuxtrtbtnnwrshqneawdghirfaturhpwesptebb'"
+ ]
+ },
+ "execution_count": 104,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bifid_decipher(c7br, 'trinket', KeywordWrapAlphabet.from_a)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}