Updated for challenge 9
[cipher-tools.git] / 2014 / 2014-challenge4.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 5,
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.keyword_cipher import *\n",
21 "from cipher.column_transposition import *\n",
22 "from cipher.railfence import *\n",
23 "from support.utilities import *\n",
24 "from support.text_prettify import *\n",
25 "from support.language_models import *\n",
26 "from support.plot_frequency_histogram import *\n",
27 "\n",
28 "c4a = open('4a.ciphertext').read()\n",
29 "c4b = open('4b.ciphertext').read()"
30 ]
31 },
32 {
33 "cell_type": "code",
34 "execution_count": 2,
35 "metadata": {},
36 "outputs": [
37 {
38 "data": {
39 "text/plain": [
40 "<matplotlib.axes._subplots.AxesSubplot at 0x7f70e84948d0>"
41 ]
42 },
43 "execution_count": 2,
44 "metadata": {},
45 "output_type": "execute_result"
46 },
47 {
48 "data": {
49 "image/png": "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\n",
50 "text/plain": [
51 "<matplotlib.figure.Figure at 0x7f70e8494080>"
52 ]
53 },
54 "metadata": {},
55 "output_type": "display_data"
56 }
57 ],
58 "source": [
59 "freqs = pd.Series(english_counts)\n",
60 "freqs.plot(kind='bar')"
61 ]
62 },
63 {
64 "cell_type": "code",
65 "execution_count": 3,
66 "metadata": {},
67 "outputs": [
68 {
69 "data": {
70 "text/plain": [
71 "'prsaoegerauiadmwehdnisnrasawuaaessrefgdosogvorbeeeaartesctdfmenuibrttlmeytumtmeuaikwhutkwerwahmnpwraeesononesebatoihacineetbrotadaktgfeesyioflttlstiiaeosvieonsrrtaupmnnoaencocnuvrsclvdrgctaiihriciaihrsduomrlemcrngleomarfhiuewhalcsasracufrawwsmehulstoaohceletmtoilsepdmumtptrslyrhhntpanwpmoadppdwbeseoassltmlpesletuncorerlclitaosvsiniifwseafortaaduyenenonnsopfhontwkoertcslyvoeiohlufoeioetsthtsbreneveaouepgieesobduorsfeercdyadutaepeadrdigseebfuoggopogalyfewsoeemdntohrebhaaesneworgnfiaulnlwadueodcotrargvuenewhiertlauilmsoniotmuinewaiuewloerstttisdrsasnussiesmerdhetryrhpnlrtereadmredebnntrnenwmoutrdosaneowomcgidciasaontiioiascesissupcrmoybrineyweelaylewtyrtilhsto'"
72 ]
73 },
74 "execution_count": 3,
75 "metadata": {},
76 "output_type": "execute_result"
77 }
78 ],
79 "source": [
80 "c4bs = sanitise(c4b)\n",
81 "c4bs"
82 ]
83 },
84 {
85 "cell_type": "code",
86 "execution_count": 6,
87 "metadata": {},
88 "outputs": [
89 {
90 "data": {
91 "text/plain": [
92 "(('stern', <KeywordWrapAlphabet.from_largest: 3>), -830.5838133421847)"
93 ]
94 },
95 "execution_count": 6,
96 "metadata": {},
97 "output_type": "execute_result"
98 }
99 ],
100 "source": [
101 "key_a, score = keyword_break_mp(c4a)\n",
102 "key_a, score"
103 ]
104 },
105 {
106 "cell_type": "code",
107 "execution_count": 7,
108 "metadata": {},
109 "outputs": [
110 {
111 "name": "stdout",
112 "output_type": "stream",
113 "text": [
114 "harry we completed the survey and you are not going to believe what we found behind the false\n",
115 "bulkhead in the stern there was a large pumping station connected to a number of sea facing outlets\n",
116 "it looks like a scuttling valve system similar to the ones used on u boats in world war two icant\n",
117 "understand why they would goto so much effort when they could have scuttled her at anytime with a\n",
118 "small quantity of plastic explosive the team back at nsa have run some analytics on the remaining\n",
119 "text files we extracted from the servers onboard these ciphers are going to be pretty hard to crack\n",
120 "the attached report has frequency analysis matching usual english text so we can assume that the\n",
121 "sender was a native speaker did you have any thoughts on what the nautilus system might have been or\n",
122 "what it was for\n"
123 ]
124 }
125 ],
126 "source": [
127 "print(prettify(keyword_decipher(sanitise(c4a), key_a[0], key_a[1])))"
128 ]
129 },
130 {
131 "cell_type": "code",
132 "execution_count": 8,
133 "metadata": {},
134 "outputs": [
135 {
136 "data": {
137 "text/plain": [
138 "(((6, 0, 1, 7, 9, 4, 2, 3, 5, 8, 10), False, True), -1777.161911681522)"
139 ]
140 },
141 "execution_count": 8,
142 "metadata": {},
143 "output_type": "execute_result"
144 }
145 ],
146 "source": [
147 "key_b, score = column_transposition_break_mp(c4bs)\n",
148 "key_b, score"
149 ]
150 },
151 {
152 "cell_type": "code",
153 "execution_count": 9,
154 "metadata": {},
155 "outputs": [
156 {
157 "name": "stdout",
158 "output_type": "stream",
159 "text": [
160 "et et mlpdshgnbralwrrauiur tep as gsl di ocpedacnscbtsesuotut ira la lee a so at dy de og is as\n",
161 "tavrtdeiioalkoducrhe hom tein oarscnegigctuimetyfo so rice lite her a aire iue leer dad tom sub rg\n",
162 "mihm it yfflvwhetamioucuer to seo e oleh sri cu fig in ddy lea log ten urs site oawioheikttpohsmpps\n",
163 "wlsosinrndshstgverll muut has ra erupt it lit smt mck is yn lace trw a bfi awrr pm eere i uunet or\n",
164 "oe wfi a gary ws nsw lal dsb aveo smee mlr hive essor yim eee a osmer n no amf nrad hep no do ie re\n",
165 "hywsunroffbnwrretttg hn tear po amd in peet gh au out ale air di serna sue eu now\n",
166 "nwyopebyegheplnmshew van me on o an aol w own nbae irc mateo de nubs odys a usoe eau pre e on n west\n",
167 "ptbnrenlerrdiacswsoa a dwl to foo ea cob hoc erp rr uses in egf st fast hurn hterneoavcfotsaeocrd\n",
168 "int cwo a is y at it wwsncauwsdsoseldlkdf mm levu norm ect\n"
169 ]
170 }
171 ],
172 "source": [
173 "print(prettify(sanitise(column_transposition_decipher(sanitise(c4bs), key_b[0], \n",
174 " fillcolumnwise=key_b[1],\n",
175 " emptycolumnwise=key_b[2]))))"
176 ]
177 },
178 {
179 "cell_type": "code",
180 "execution_count": 10,
181 "metadata": {},
182 "outputs": [
183 {
184 "data": {
185 "text/plain": [
186 "(((4, 8, 0, 6, 9, 3, 1, 2, 5, 7, 10), False, True), -2823.7851213306785)"
187 ]
188 },
189 "execution_count": 10,
190 "metadata": {},
191 "output_type": "execute_result"
192 }
193 ],
194 "source": [
195 "key_b, score = column_transposition_break_mp(c4bs, fitness=Ptrigrams)\n",
196 "key_b, score"
197 ]
198 },
199 {
200 "cell_type": "code",
201 "execution_count": 11,
202 "metadata": {},
203 "outputs": [
204 {
205 "name": "stdout",
206 "output_type": "stream",
207 "text": [
208 "te tmpl dsehgbralrwranuirtep sag sul doc pea dc nisc tses out ub tial a lee as road yd egoist as avr\n",
209 "ted ii to ako durch el hote in a or smc n gig cut i meet fo soir cey lie her a air te ie leed radu\n",
210 "to sub rmg ihmmiyfflwvhettaiouc eur tmo so eol hes re ic fig id nd yule log tn eur ass teoa\n",
211 "iwohieittposhmpkpsl so snirnwdsstgvrellhmut has are ru up it list mttmcisynalcektrabfi war rwp mere\n",
212 "iuu nee too ew fai garry sns wall dwsbveosememalrivees so rhy ieee a some mr no am frn adn he no do\n",
213 "eire phys un rf of bwnwrettgthnrterpo admin a petg hao uu tea laird sie renau eeuonwnswypebygeheo\n",
214 "plm she vw ann me no a no al woo wnba eric mn a to den bus oed yau so eea us pre on new step tn rene\n",
215 "lrrbdicswsaoadawl of ooaecotbhcerprrusoes neg ft sfa is turn he trn he ovc fost aea ord inc two cas\n",
216 "ya ttiw wisc au wds sons ldlkfdmmelvunomrecet\n"
217 ]
218 }
219 ],
220 "source": [
221 "print(prettify(sanitise(column_transposition_decipher(sanitise(c4bs), key_b[0], \n",
222 " fillcolumnwise=key_b[1], \n",
223 " emptycolumnwise=key_b[2]))))"
224 ]
225 },
226 {
227 "cell_type": "code",
228 "execution_count": 12,
229 "metadata": {},
230 "outputs": [
231 {
232 "data": {
233 "text/plain": [
234 "<matplotlib.axes._subplots.AxesSubplot at 0x7f70a1377dd8>"
235 ]
236 },
237 "execution_count": 12,
238 "metadata": {},
239 "output_type": "execute_result"
240 },
241 {
242 "data": {
243 "image/png": "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\n",
244 "text/plain": [
245 "<matplotlib.figure.Figure at 0x7f70a30f36d8>"
246 ]
247 },
248 "metadata": {},
249 "output_type": "display_data"
250 }
251 ],
252 "source": [
253 "freqs_4b = pd.Series(collections.Counter([l.lower() for l in c4b if l in string.ascii_letters]))\n",
254 "freqs_4b.plot(kind='bar')"
255 ]
256 },
257 {
258 "cell_type": "code",
259 "execution_count": 13,
260 "metadata": {},
261 "outputs": [
262 {
263 "data": {
264 "text/plain": [
265 "(5, -1581.9784460662272)"
266 ]
267 },
268 "execution_count": 13,
269 "metadata": {},
270 "output_type": "execute_result"
271 }
272 ],
273 "source": [
274 "railfence_break(c4bs)"
275 ]
276 },
277 {
278 "cell_type": "code",
279 "execution_count": 14,
280 "metadata": {},
281 "outputs": [
282 {
283 "name": "stdout",
284 "output_type": "stream",
285 "text": [
286 "phase four the decks were cleared by two am and the mounting plates were prepared and measured\n",
287 "mounting points were assembled by four am though owing to the approaching dawn deployment of seabird\n",
288 "was postponed and we embarked onstage two of seahorse assembly with camouflage plates installed we\n",
289 "set to cruising in case of air or sea surveillance following standard routes to avoid suspicion\n",
290 "monitoring of airwaves gave no cause for concern but we have raised security levels and are using a\n",
291 "column transposition cipher for this communication with keyword seabird future comms will relyon\n",
292 "even more security tonight will be used for more sea trials of the nautilus system while the\n",
293 "assembly crew rest and the survey team carryout further mapping we will resume the seahorse build at\n",
294 "dusk tomorrow\n"
295 ]
296 }
297 ],
298 "source": [
299 "print(prettify(railfence_decipher(c4bs, 5)))"
300 ]
301 },
302 {
303 "cell_type": "code",
304 "execution_count": null,
305 "metadata": {},
306 "outputs": [],
307 "source": []
308 }
309 ],
310 "metadata": {
311 "kernelspec": {
312 "display_name": "Python 3",
313 "language": "python",
314 "name": "python3"
315 },
316 "language_info": {
317 "codemirror_mode": {
318 "name": "ipython",
319 "version": 3
320 },
321 "file_extension": ".py",
322 "mimetype": "text/x-python",
323 "name": "python",
324 "nbconvert_exporter": "python",
325 "pygments_lexer": "ipython3",
326 "version": "3.6.3"
327 }
328 },
329 "nbformat": 4,
330 "nbformat_minor": 1
331 }