Updated for challenge 9
[cipher-tools.git] / 2014 / 2014-challenge2.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 6,
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 "c2a = open('2a.ciphertext').read()\n",
28 "c2b = open('2b.ciphertext').read()"
29 ]
30 },
31 {
32 "cell_type": "code",
33 "execution_count": 3,
34 "metadata": {},
35 "outputs": [
36 {
37 "data": {
38 "text/plain": [
39 "<matplotlib.axes._subplots.AxesSubplot at 0x7fd7aa938668>"
40 ]
41 },
42 "execution_count": 3,
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 0x7fd7abfb7860>"
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": 4,
65 "metadata": {},
66 "outputs": [
67 {
68 "data": {
69 "text/plain": [
70 "((5, 25, True), -761.8388033231918)"
71 ]
72 },
73 "execution_count": 4,
74 "metadata": {},
75 "output_type": "execute_result"
76 }
77 ],
78 "source": [
79 "key_a, score = affine_break(c2a)\n",
80 "key_a, score"
81 ]
82 },
83 {
84 "cell_type": "code",
85 "execution_count": 5,
86 "metadata": {},
87 "outputs": [
88 {
89 "name": "stdout",
90 "output_type": "stream",
91 "text": [
92 "DEAR MARK, \n",
93 "\n",
94 "THANKS FOR THE LATEST REPORT FROM THE ON-SITE TEAM. IT SHOWS THAT THE SHIPBOARD GPS SYSTEM WAS COMPLETELY SCRAMBLED SO WE ARE NOT GOING TO BE ABLE TO TRACE HER MOVEMENTS FROM THAT. DO WE HAVE ANY ODD TRACES FROM ONSHORE RADAR THAT GIVE A HINT OF WHERE SHE MIGHT HAVE BEEN? \n",
95 "\n",
96 "THE COMMENT IN THE LAST MESSAGE THAT THE PIRATES COMPLETED THE SURVEY EVEN THOUGH THEY HAD MOVED SOUTH TO AVOID DETECTION SHOULD HAVE TOLD ME THAT THE SURVEY WAS NOT GEOGRAPHIC. AT FIRST I THOUGHT IT MIGHT HAVE BEEN REFERRING TO A TELECOMS SURVEY SINCE YOU MENTIONED THE LONG AERIAL, BUT ACTUALLY THE ATTACHED MESSAGE IS VERY REVEALING. STILL NOT SURE WHAT THE SURVEY WAS FOR THOUGH, AND HOW THAT IS CONNECTED TO THE MISSING SUPERSTRUCTURE. CAN YOU GET ME ANY PICTURES? \n",
97 "\n",
98 "HARRY \n",
99 "\n"
100 ]
101 }
102 ],
103 "source": [
104 "print(affine_decipher(c2a, key_a[0], key_a[1]))"
105 ]
106 },
107 {
108 "cell_type": "code",
109 "execution_count": 7,
110 "metadata": {},
111 "outputs": [
112 {
113 "data": {
114 "text/plain": [
115 "(('flag', <KeywordWrapAlphabet.from_largest: 3>), -367.81492429457404)"
116 ]
117 },
118 "execution_count": 7,
119 "metadata": {},
120 "output_type": "execute_result"
121 }
122 ],
123 "source": [
124 "key_b, score = keyword_break_mp(c2b)\n",
125 "key_b, score"
126 ]
127 },
128 {
129 "cell_type": "code",
130 "execution_count": 8,
131 "metadata": {},
132 "outputs": [
133 {
134 "name": "stdout",
135 "output_type": "stream",
136 "text": [
137 "calm weather allowed us to complete the hull survey and establish its integrity no major remedial\n",
138 "works were required and the pumps and extra bulkheads were installed out in deep waters over the\n",
139 "next five days we are now testing the system for reliability and safety before moving on to phase\n",
140 "three of the operation operation trojan remains on target\n"
141 ]
142 }
143 ],
144 "source": [
145 "print(lcat(tpack(segment(sanitise(keyword_decipher(c2b, key_b[0], key_b[1]))))))"
146 ]
147 },
148 {
149 "cell_type": "code",
150 "execution_count": 9,
151 "metadata": {},
152 "outputs": [
153 {
154 "data": {
155 "text/plain": [
156 "<matplotlib.axes._subplots.AxesSubplot at 0x7fd7a6ada710>"
157 ]
158 },
159 "execution_count": 9,
160 "metadata": {},
161 "output_type": "execute_result"
162 },
163 {
164 "data": {
165 "image/png": "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\n",
166 "text/plain": [
167 "<matplotlib.figure.Figure at 0x7fd7a6adad68>"
168 ]
169 },
170 "metadata": {},
171 "output_type": "display_data"
172 }
173 ],
174 "source": [
175 "freqs_2b = pd.Series(collections.Counter([l.lower() for l in c2b if l in string.ascii_letters]))\n",
176 "freqs_2b.plot(kind='bar')"
177 ]
178 },
179 {
180 "cell_type": "code",
181 "execution_count": null,
182 "metadata": {},
183 "outputs": [],
184 "source": []
185 }
186 ],
187 "metadata": {
188 "kernelspec": {
189 "display_name": "Python 3",
190 "language": "python",
191 "name": "python3"
192 },
193 "language_info": {
194 "codemirror_mode": {
195 "name": "ipython",
196 "version": 3
197 },
198 "file_extension": ".py",
199 "mimetype": "text/x-python",
200 "name": "python",
201 "nbconvert_exporter": "python",
202 "pygments_lexer": "ipython3",
203 "version": "3.6.3"
204 }
205 },
206 "nbformat": 4,
207 "nbformat_minor": 1
208 }