Updated for challenge 9
[cipher-tools.git] / 2014 / 2014-challenge3.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {},
7 "outputs": [],
8 "source": [
9 "import os,sys,inspect\n",
10 "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
11 "parentdir = os.path.dirname(currentdir)\n",
12 "sys.path.insert(0,parentdir) \n",
13 "\n",
14 "import matplotlib.pyplot as plt\n",
15 "import pandas as pd\n",
16 "import collections\n",
17 "import string\n",
18 "%matplotlib inline\n",
19 "\n",
20 "from cipher.affine import *\n",
21 "from cipher.keyword_cipher import *\n",
22 "from support.utilities import *\n",
23 "from support.text_prettify import *\n",
24 "from support.language_models import *\n",
25 "from support.plot_frequency_histogram import *\n",
26 "\n",
27 "c3a = open('3a.ciphertext').read()\n",
28 "c3b = open('3b.ciphertext').read()"
29 ]
30 },
31 {
32 "cell_type": "code",
33 "execution_count": 2,
34 "metadata": {},
35 "outputs": [
36 {
37 "data": {
38 "text/plain": [
39 "<matplotlib.axes._subplots.AxesSubplot at 0x7f6c8409bac8>"
40 ]
41 },
42 "execution_count": 2,
43 "metadata": {},
44 "output_type": "execute_result"
45 },
46 {
47 "data": {
48 "image/png": "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\n",
49 "text/plain": [
50 "<matplotlib.figure.Figure at 0x7f6c8409b240>"
51 ]
52 },
53 "metadata": {},
54 "output_type": "display_data"
55 }
56 ],
57 "source": [
58 "freqs = pd.Series(english_counts)\n",
59 "freqs.plot(kind='bar')"
60 ]
61 },
62 {
63 "cell_type": "code",
64 "execution_count": 3,
65 "metadata": {},
66 "outputs": [
67 {
68 "data": {
69 "text/plain": [
70 "((11, 1, True), -839.4977013876568)"
71 ]
72 },
73 "execution_count": 3,
74 "metadata": {},
75 "output_type": "execute_result"
76 }
77 ],
78 "source": [
79 "key_a, score = affine_break(c3a)\n",
80 "key_a, score"
81 ]
82 },
83 {
84 "cell_type": "code",
85 "execution_count": 4,
86 "metadata": {},
87 "outputs": [
88 {
89 "name": "stdout",
90 "output_type": "stream",
91 "text": [
92 "harry you asked me about the flag day associates they area transnational hacking group dedicated to\n",
93 "the overthrow of western capitalism they have been implicated in several major protests including an\n",
94 "attempt to takeover the uk national grid attacks on reservoir systems and interference in bank\n",
95 "trading networks it looks like the fda carried out fairly extensive modifications to the ship they\n",
96 "did a good job too we hadnt noticed the added bulkheads until we compared the layout with the plans\n",
97 "from lloyds register they seem to be there to add rigidity though there is one additional panel at\n",
98 "the stern that doesnt fit the pattern and we will be removing that tonight to see what it is there\n",
99 "for we would have done it this afternoon but decided we should conduct our own hull survey in case\n",
100 "there is a booby trap\n"
101 ]
102 }
103 ],
104 "source": [
105 "print(lcat(tpack(segment(affine_decipher(sanitise(c3a), key_a[0], key_a[1])))))"
106 ]
107 },
108 {
109 "cell_type": "code",
110 "execution_count": 5,
111 "metadata": {},
112 "outputs": [
113 {
114 "data": {
115 "text/plain": [
116 "(('seahorse', <KeywordWrapAlphabet.from_last: 2>), -681.3308426043137)"
117 ]
118 },
119 "execution_count": 5,
120 "metadata": {},
121 "output_type": "execute_result"
122 }
123 ],
124 "source": [
125 "key_b, score = keyword_break_mp(c3b)\n",
126 "key_b, score"
127 ]
128 },
129 {
130 "cell_type": "code",
131 "execution_count": 6,
132 "metadata": {},
133 "outputs": [
134 {
135 "name": "stdout",
136 "output_type": "stream",
137 "text": [
138 "phase three the nautilus system was fully tested last night with complete success we sailed within\n",
139 "four hundred metres of the target and monitored all radio traffic for two hours with no sign that we\n",
140 "were being watched or were even noticed we then conducted a full radar sweep of the area and found\n",
141 "three dead spots where we could work on the ship without detection as planned we converted the two\n",
142 "adjacent empty containers in the middle of the stack into a large workshop area and carried out a\n",
143 "full inspection drill now even if we are boarded our work should remain undetected we retrieved\n",
144 "seahorse from the third container and carried out stage one of the assembly\n"
145 ]
146 }
147 ],
148 "source": [
149 "print(lcat(tpack(segment(sanitise(keyword_decipher(c3b, key_b[0], key_b[1]))))))"
150 ]
151 },
152 {
153 "cell_type": "code",
154 "execution_count": 7,
155 "metadata": {},
156 "outputs": [
157 {
158 "data": {
159 "text/plain": [
160 "<matplotlib.axes._subplots.AxesSubplot at 0x7f6c42fd9a20>"
161 ]
162 },
163 "execution_count": 7,
164 "metadata": {},
165 "output_type": "execute_result"
166 },
167 {
168 "data": {
169 "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD7CAYAAAB68m/qAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAE7xJREFUeJzt3X+w3XV95/HnC1BRlpYA12yWGEMLA3W6gnBFHNFdQVxaaclukcWtNHXRzK61i7W/stuurB27Qqu19se0mwFtpmoRKGzY2rVlIh21UkoSKCg/BoxgkwnkqgSpa4XY9/5xvhmv4d57vvfce3NvPnk+Zu6c8/2e7+d83jn5ntf5nM853+9JVSFJOvgdttgFSJLmh4EuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGmGgS1IjDHRJasQRB7Kz448/vlavXn0gu5Skg97WrVu/WlVjw7Y7oIG+evVqtmzZciC7lKSDXpJH+2znlIskNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEb0OLEryc8BbgQLuBd4CrACuA44DtgKXVdXTC1SntGSsXv/JaW975Ko3HMBKpO81dISe5ATgvwDjVfXDwOHApcDVwAer6iTgCeDyhSxUkjSzvlMuRwDPT3IE8AJgF3AucGN3+0ZgzfyXJ0nqa2igV9VO4P3AVxgE+ZMMplj2VNXebrMdwAlTtU+yLsmWJFsmJibmp2pJ0rP0mXJZBlwEnAj8C+Ao4IK+HVTVhqoar6rxsbGhJwuTJI2oz5TL64AvV9VEVT0D3AS8Cjimm4IBWAnsXKAaJUk99An0rwBnJ3lBkgDnAfcBtwEXd9usBTYtTImSpD76zKHfweDDz20MvrJ4GLAB+GXgXUkeZvDVxWsXsE5J0hC9vodeVVcCV+63ejtw1rxXJEkaiUeKSlIjDHRJaoSBLkmNMNAlqREGuiQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNcJAl6RGGOiS1AgDXZIa0edHok9Jcvekv28keWeSY5PcmuSh7nLZgShYkjS1Pj9B92BVnV5VpwNnAv8PuBlYD2yuqpOBzd2yJGmRzHbK5TzgS1X1KHARsLFbvxFYM5+FSZJmZ7aBfinwJ9315VW1q7v+GLB8qgZJ1iXZkmTLxMTEiGVKkobpHehJngv8OHDD/rdVVQE1Vbuq2lBV41U1PjY2NnKhkqSZzWaE/iPAtqp6vFt+PMkKgO5y93wXJ0nqbzaB/ia+O90CcAuwtru+Ftg0X0VJkmavV6AnOQo4H7hp0uqrgPOTPAS8rluWJC2SI/psVFXfBI7bb93XGHzrRZK0BHikqCQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEQa6JDWi70/QHZPkxiQPJLk/ySuTHJvk1iQPdZfLFrpYSdL0+o7QPwR8qqpOBU4D7gfWA5ur6mRgc7csSVokQwM9yfcDrwGuBaiqp6tqD3ARsLHbbCOwZqGKlCQN12eEfiIwAXwkyV1JrklyFLC8qnZ12zwGLJ+qcZJ1SbYk2TIxMTE/VUuSnqVPoB8BnAH8QVW9DPgm+02vVFUBNVXjqtpQVeNVNT42NjbXeiVJ0+gT6DuAHVV1R7d8I4OAfzzJCoDucvfClChJ6mNooFfVY8DfJzmlW3UecB9wC7C2W7cW2LQgFUqSejmi53Y/C3wsyXOB7cBbGLwYXJ/kcuBR4JKFKVGS1EevQK+qu4HxKW46b37LkSSNyiNFJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEX0P/ZeGWr3+k9Pe9shVbziAlUiHJkfoktQIA12SGmGgS1IjDHRJaoSBLkmNMNAlqRG9vraY5BHgKeA7wN6qGk9yLPAJYDXwCHBJVT2xMGVKkoaZzQj9tVV1elXt++Wi9cDmqjoZ2NwtS5IWyVymXC4CNnbXNwJr5l6OJGlUfQO9gL9MsjXJum7d8qra1V1/DFg+VcMk65JsSbJlYmJijuVKkqbT99D/c6pqZ5IXArcmeWDyjVVVSWqqhlW1AdgAMD4+PuU2kqS56zVCr6qd3eVu4GbgLODxJCsAusvdC1WkJGm4oYGe5KgkR++7Drwe+AJwC7C222wtsGmhipQkDddnymU5cHOSfdt/vKo+leRO4PoklwOPApcsXJmSpGGGBnpVbQdOm2L914DzFqIoSdLseaSoJDXCQJekRhjoktQIA12SGmGgS1IjDHRJaoSBLkmNMNAlqREGuiQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNaLPT9ABkORwYAuws6ouTHIicB1wHLAVuKyqnl6YMufP6vWfnPa2R656wwGsRDow3OcPHbMZoV8B3D9p+Wrgg1V1EvAEcPl8FiZJmp1egZ5kJfAG4JpuOcC5wI3dJhuBNQtRoCSpn75TLr8N/BJwdLd8HLCnqvZ2yzuAE6ZqmGQdsA5g1apVo1d6CJrprTL4dlnS9xo6Qk9yIbC7qraO0kFVbaiq8aoaHxsbG+UuJEk99Bmhvwr48SQ/ChwJfB/wIeCYJEd0o/SVwM6FK1OSNMzQEXpV/deqWllVq4FLgU9X1U8CtwEXd5utBTYtWJWSpKHm8j30XwbeleRhBnPq185PSZKkUfT+HjpAVf0V8Ffd9e3AWfNfkiRpFB4pKkmNMNAlqREGuiQ1wkCXpEbM6kPRpcKTDUnSszlCl6RGGOiS1IiDcspFwzktJR16HKFLUiMMdElqhIEuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGtHnR6KPTPK3Sf4uyReTvKdbf2KSO5I8nOQTSZ678OVKkqbTZ4T+beDcqjoNOB24IMnZwNXAB6vqJOAJ4PKFK1OSNEyfH4muqvqHbvE53V8B5wI3dus3AmsWpEJJUi+9zuWS5HBgK3AS8PvAl4A9VbW322QHcMI0bdcB6wBWrVo113olNWymcxCB5yEapteHolX1nao6HVjJ4IehT+3bQVVtqKrxqhofGxsbsUxJ0jCz+pZLVe0BbgNeCRyTZN8IfyWwc55rkyTNwtAplyRjwDNVtSfJ84HzGXwgehtwMXAdsBbYtJCF6sDwLa908Oozh74C2NjNox8GXF9Vf5bkPuC6JO8F7gKuXcA6JUlDDA30qroHeNkU67czmE+XJC0B/mKRpHnnL2YtDg/9l6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGuG5XHTI8nwjao0jdElqhIEuSY0w0CWpEQa6JDViaKAneVGS25Lcl+SLSa7o1h+b5NYkD3WXyxa+XEnSdPqM0PcCP19VLwHOBn4myUuA9cDmqjoZ2NwtS5IWydBAr6pdVbWtu/4UcD9wAnARsLHbbCOwZqGKlCQNN6vvoSdZzeAHo+8AllfVru6mx4Dl07RZB6wDWLVq1ah1StKSs9SOZej9oWiSfwb8KfDOqvrG5NuqqoCaql1Vbaiq8aoaHxsbm1OxkqTp9Qr0JM9hEOYfq6qbutWPJ1nR3b4C2L0wJUqS+hg65ZIkwLXA/VX1W5NuugVYC1zVXW6aTcczvVUBD72WpNnqM4f+KuAy4N4kd3fr/huDIL8+yeXAo8AlC1OiJKmPoYFeVZ8DMs3N581vOToU+W5Nmh8eKSpJjTDQJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY2Y1elzJS0Oj6ZVH47QJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqxNBAT/LhJLuTfGHSumOT3Jrkoe5y2cKWKUkaps8I/Y+AC/Zbtx7YXFUnA5u7ZUnSIhoa6FX1GeDr+62+CNjYXd8IrJnnuiRJszTqHPryqtrVXX8MWD7dhknWJdmSZMvExMSI3UmShpnzh6JVVUDNcPuGqhqvqvGxsbG5didJmsaoJ+d6PMmKqtqVZAWwez6LWopmOjmSJ0aSNFsLkSmjjtBvAdZ219cCm0a8H0nSPOnztcU/AW4HTkmyI8nlwFXA+UkeAl7XLUuSFtHQKZeqetM0N503z7VIkubAI0UlqREGuiQ1wkCXpEYY6JLUCH8kWtKU/GHqg48jdElqhIEuSY0w0CWpEQa6JDXCD0V1UDvYTpp2sNV7qGjl/8URuiQ1wkCXpEY45XIAtPJ2TtLS5ghdkhphoEtSIwx0SWrEnAI9yQVJHkzycJL181WUJGn2Rv5QNMnhwO8D5wM7gDuT3FJV981XcZLUl18+mNsI/Szg4araXlVPA9cBF81PWZKk2UpVjdYwuRi4oKre2i1fBryiqt6x33brgHXd4inAg9Pc5fHAV0cqZvS29rk029pnW33Opa19Dry4qsaG3ktVjfQHXAxcM2n5MuD35nB/Ww50W/tcmm3ts60+D7Z6D7Y+J//NZcplJ/CiScsru3WSpEUwl0C/Ezg5yYlJngtcCtwyP2VJkmZr5G+5VNXeJO8A/gI4HPhwVX1xDrVsWIS29rk029pnW33Opa19zsLIH4pKkpYWjxSVpEYY6JLUCANdOghk4EXDt9ShbNEDPcmyJGclec2+v57tjkzyriQ3JfnTJD+X5MiFrncU3ZPxzUne3S2vSnLWYtc1H5J8rrt8Ksk39vt7MsmXk7y9x/2cOcW6Cxei5vmQ5LQk7+j+TptFu5H22xp82PXnI9b6xiRHd9d/tev7jB7tru6zbj51j80JI7b9aJK3JTl1hLYvmWLdv+7R7meTLJttf13bzUl+dL91c/pwdFE/FE3yVuAKBt9hvxs4G7i9qs7t0fZ64Cngo92q/wAcU1VvHNJuI3BFVe3plpcBH6iq/zjN9u+a6f6q6rd61PoHwD8B51bVD3V9/mVVvXxIu6n6fhLYWlV3D2n7POAngNVM+jZTVf3asHrnU5LjgM9X1SlDttsG/FRVfaFbfhPwzqp6xQLWNg78CvBiBo9RGGTnS4e0uwJ4G3BTt+rfAhuq6nd79DnSftu13cjg4L07h227X7t7quqlSc4B3gv8JvDuYY9tkm1VdcZ+6+4Z9vh02717qvXD9r8kVwKXAF8HPgHcUFWPD+uva/ta4NXd3w8CdwGfqaoP9Wj7BeCPgd8Ajuwux6vqlUPavZfBV7a3AR8G/qJ6hmqS7cDfA5+uqvd06571mM/GYgf6vcDLgb+pqtO7V9b/WVX/rkfb+6rqJcPWTdHurqp62bB1k267srt6Slfrvu/a/xjwt1X15h61bquqMyb3k+TvqmrGkV2SjwPjwP/pVl0I3MMgpG+oqt+Yoe2n6MIf+M6+9VX1gRnafK6qzknyFDB5x9gXdN83U70z3O+Kqto1ZJsfAG5kEHCvBn4KuLCqnpyhzf51zqreJA8Cvwjcy+AFFwYNHx3S7h7glVX1zW75KAYDkT5BN9J+2233AHAS8CjwTfq/AN1VVS9L8j7g3qr6+JB9/j8Dbwd+APjSpJuOBv665z7/85MWj2Sw794/3cBpivYvBf49g0HJjqp6Xc92hzN4nr4W+E/At6pq6Ii9+z+8GjiTwb/zY8DVVfVPMzYctA3weuAtDJ6v1wPXVtWXhrTbxuCcWL/D4CDNNwO3zSXQF/sn6P6xqv4xCUmeV1UPJJlxJDfJtiRnV9XfACR5BbClR7vDkiyrqie6dscyw+Mw6ZXzM8AZVfVUt/w/gOlP7/a9nul2tOrajjEpQGawsuvzH7p2V3Z9voZBUE8b6MDKqrqgZ30AVNU53eXRs2nX435nDPNum+1JLgX+N/AV4PVV9a0hbeZa50RVjXIwXJj0ItldT8+2o+63AP+mf4nfY2eS/8XgzKhXd+/eZppu/Tjwf4H3AZNPi/1UVX29T4f7DxySvJ/BMSt97QYeA74GvLBPgySbgaOA24HPAi+vqt09+3sG+BbwfAYvQF/uE+YweEVN8lhX715gGXBjklur6pdmKrmq9gJvT/LTwOe6tiNb7EDfkeQYBk/iW5M8wWD0Ma1uVF/Ac4DPJ/lKt/xi4IEefX4AuD3JDd3yG4Ff79FuOfD0pOWnu3V9/A5wM/DCJL/O4Dw4v9qj3QuBb09afgZYXlXfSvLtadrs8/kk/7Kq7u1Z46KY9P+5z7EMDlS7Iwl9Rr1zcGWSa4DNTHqcq+qm6ZsA8JGuvpu75TXAtT37PJPv7rcAq4AH9z0OM/17h71zmMElwAXA+6tqT5IVDN6ZTNfPkwze3b1pxP6m8gIGA5QZZfB5yyXAGHAD8Lbqf0ruexg8vj/MoP49SW4fNjDo3AlsYjC6Px74wyQ/0WMK9woG7ya/ClwD/GJVPZPkMOAhYKZA/8N9V6rqj7p94Gd61Dp9PUvlwKIk/wr4fuBTNTgd73TbvXim++mz03cfgOybp/90nx0mya8w2NEmP4k/UVXvG9a2a38qcB6Dkdzmqrq/R5v/zmB+dlO36scYTPl8gMGc7U9O0WZfQB4BnAxsZxBWvd6eH2jz8f85h74/CpwKfJHvvmOqPtMC3YeK53SLn62qu3r2uWj/3gNpvxfqwxkE9K9V1e8Nafc+Bs+rGT8jGnIfRwM/DfwC8M+r6nk92oxX1Zb91l1WVX88pN17GBwl/6z/tyQ/1Od5Pp+WTKAfDLon8au7xc/0fRLPsc9x4FXd4l/vv9NNsf0hERjzIcmDwz6s1Wj22w/3Ao930wsL2ec7GDw/zwQeYTDt8tmq+vRC9ruUGOg6ZCX5CPCbs3hLryUsyS8wCPGtC/3isVQZ6DpkJbmfwdfbvswSnpaS+jLQdciabnrKaSkdrAx0SWrEoh/6L0maHwa6JDXCQJekRhjoktSI/w91dSCiPmyo1wAAAABJRU5ErkJggg==\n",
170 "text/plain": [
171 "<matplotlib.figure.Figure at 0x7f6c430c56a0>"
172 ]
173 },
174 "metadata": {},
175 "output_type": "display_data"
176 }
177 ],
178 "source": [
179 "freqs_3b = pd.Series(collections.Counter([l.lower() for l in c3b if l in string.ascii_letters]))\n",
180 "freqs_3b.plot(kind='bar')"
181 ]
182 },
183 {
184 "cell_type": "code",
185 "execution_count": null,
186 "metadata": {},
187 "outputs": [],
188 "source": []
189 }
190 ],
191 "metadata": {
192 "kernelspec": {
193 "display_name": "Python 3",
194 "language": "python",
195 "name": "python3"
196 },
197 "language_info": {
198 "codemirror_mode": {
199 "name": "ipython",
200 "version": 3
201 },
202 "file_extension": ".py",
203 "mimetype": "text/x-python",
204 "name": "python",
205 "nbconvert_exporter": "python",
206 "pygments_lexer": "ipython3",
207 "version": "3.6.3"
208 }
209 },
210 "nbformat": 4,
211 "nbformat_minor": 1
212 }