Updated for challenge 9
[cipher-tools.git] / bifid-ciphers.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": false
8 },
9 "outputs": [],
10 "source": [
11 "import matplotlib.pyplot as plt\n",
12 "import pandas as pd\n",
13 "import collections\n",
14 "import string\n",
15 "import numpy as np\n",
16 "from numpy import matrix\n",
17 "from numpy import linalg\n",
18 "%matplotlib inline\n",
19 "\n",
20 "from multiprocessing import Pool\n",
21 "\n",
22 "\n",
23 "from cipher import *\n",
24 "from cipherbreak import *\n",
25 "\n",
26 "c7b = open('2016/7b.ciphertext').read()"
27 ]
28 },
29 {
30 "cell_type": "code",
31 "execution_count": 108,
32 "metadata": {
33 "collapsed": true
34 },
35 "outputs": [],
36 "source": [
37 "c7bs = sanitise(c7b)\n",
38 "c7br = cat(reversed(c7bs))"
39 ]
40 },
41 {
42 "cell_type": "code",
43 "execution_count": 2,
44 "metadata": {
45 "collapsed": true
46 },
47 "outputs": [],
48 "source": [
49 "def bifid_grid(keyword, wrap_alphabet, letter_mapping):\n",
50 " cipher_alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet)\n",
51 " if letter_mapping is None:\n",
52 " letter_mapping = {'j': 'i'}\n",
53 " translation = ''.maketrans(letter_mapping)\n",
54 " cipher_alphabet = cat(collections.OrderedDict.fromkeys(cipher_alphabet.translate(translation)))\n",
55 " f_grid = {k: ((i // 5) + 1, (i % 5) + 1) \n",
56 " for i, k in enumerate(cipher_alphabet)}\n",
57 " r_grid = {((i // 5) + 1, (i % 5) + 1): k \n",
58 " for i, k in enumerate(cipher_alphabet)}\n",
59 " return translation, f_grid, r_grid"
60 ]
61 },
62 {
63 "cell_type": "code",
64 "execution_count": 156,
65 "metadata": {
66 "collapsed": true
67 },
68 "outputs": [],
69 "source": [
70 "import pprint"
71 ]
72 },
73 {
74 "cell_type": "code",
75 "execution_count": 157,
76 "metadata": {
77 "collapsed": false,
78 "scrolled": true
79 },
80 "outputs": [
81 {
82 "name": "stdout",
83 "output_type": "stream",
84 "text": [
85 "({106: 'i'},\n",
86 " {'a': (1, 4),\n",
87 " 'b': (2, 1),\n",
88 " 'c': (2, 2),\n",
89 " 'd': (2, 3),\n",
90 " 'e': (2, 4),\n",
91 " 'f': (2, 5),\n",
92 " 'g': (1, 2),\n",
93 " 'h': (3, 1),\n",
94 " 'i': (1, 1),\n",
95 " 'k': (3, 2),\n",
96 " 'l': (3, 3),\n",
97 " 'm': (3, 4),\n",
98 " 'n': (1, 5),\n",
99 " 'o': (3, 5),\n",
100 " 'p': (4, 1),\n",
101 " 'q': (4, 2),\n",
102 " 'r': (4, 3),\n",
103 " 's': (4, 4),\n",
104 " 't': (4, 5),\n",
105 " 'u': (1, 3),\n",
106 " 'v': (5, 1),\n",
107 " 'w': (5, 2),\n",
108 " 'x': (5, 3),\n",
109 " 'y': (5, 4),\n",
110 " 'z': (5, 5)},\n",
111 " {(1, 1): 'i',\n",
112 " (1, 2): 'g',\n",
113 " (1, 3): 'u',\n",
114 " (1, 4): 'a',\n",
115 " (1, 5): 'n',\n",
116 " (2, 1): 'b',\n",
117 " (2, 2): 'c',\n",
118 " (2, 3): 'd',\n",
119 " (2, 4): 'e',\n",
120 " (2, 5): 'f',\n",
121 " (3, 1): 'h',\n",
122 " (3, 2): 'k',\n",
123 " (3, 3): 'l',\n",
124 " (3, 4): 'm',\n",
125 " (3, 5): 'o',\n",
126 " (4, 1): 'p',\n",
127 " (4, 2): 'q',\n",
128 " (4, 3): 'r',\n",
129 " (4, 4): 's',\n",
130 " (4, 5): 't',\n",
131 " (5, 1): 'v',\n",
132 " (5, 2): 'w',\n",
133 " (5, 3): 'x',\n",
134 " (5, 4): 'y',\n",
135 " (5, 5): 'z'})\n"
136 ]
137 }
138 ],
139 "source": [
140 "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, None))"
141 ]
142 },
143 {
144 "cell_type": "code",
145 "execution_count": 158,
146 "metadata": {
147 "collapsed": false,
148 "scrolled": true
149 },
150 "outputs": [
151 {
152 "name": "stdout",
153 "output_type": "stream",
154 "text": [
155 "({106: 'i'},\n",
156 " {'a': (1, 2),\n",
157 " 'b': (1, 3),\n",
158 " 'c': (1, 4),\n",
159 " 'd': (1, 5),\n",
160 " 'e': (2, 1),\n",
161 " 'f': (2, 2),\n",
162 " 'g': (2, 3),\n",
163 " 'h': (2, 4),\n",
164 " 'i': (2, 5),\n",
165 " 'k': (3, 1),\n",
166 " 'l': (3, 2),\n",
167 " 'm': (3, 3),\n",
168 " 'n': (3, 4),\n",
169 " 'o': (3, 5),\n",
170 " 'p': (4, 1),\n",
171 " 'q': (4, 2),\n",
172 " 'r': (4, 3),\n",
173 " 's': (4, 4),\n",
174 " 't': (4, 5),\n",
175 " 'u': (5, 1),\n",
176 " 'v': (5, 2),\n",
177 " 'w': (5, 3),\n",
178 " 'x': (5, 4),\n",
179 " 'y': (5, 5),\n",
180 " 'z': (1, 1)},\n",
181 " {(1, 1): 'z',\n",
182 " (1, 2): 'a',\n",
183 " (1, 3): 'b',\n",
184 " (1, 4): 'c',\n",
185 " (1, 5): 'd',\n",
186 " (2, 1): 'e',\n",
187 " (2, 2): 'f',\n",
188 " (2, 3): 'g',\n",
189 " (2, 4): 'h',\n",
190 " (2, 5): 'i',\n",
191 " (3, 1): 'k',\n",
192 " (3, 2): 'l',\n",
193 " (3, 3): 'm',\n",
194 " (3, 4): 'n',\n",
195 " (3, 5): 'o',\n",
196 " (4, 1): 'p',\n",
197 " (4, 2): 'q',\n",
198 " (4, 3): 'r',\n",
199 " (4, 4): 's',\n",
200 " (4, 5): 't',\n",
201 " (5, 1): 'u',\n",
202 " (5, 2): 'v',\n",
203 " (5, 3): 'w',\n",
204 " (5, 4): 'x',\n",
205 " (5, 5): 'y'})\n"
206 ]
207 }
208 ],
209 "source": [
210 "pprint.pprint(bifid_grid('z', KeywordWrapAlphabet.from_a, None))"
211 ]
212 },
213 {
214 "cell_type": "code",
215 "execution_count": 159,
216 "metadata": {
217 "collapsed": false,
218 "scrolled": true
219 },
220 "outputs": [
221 {
222 "name": "stdout",
223 "output_type": "stream",
224 "text": [
225 "({113: 'p'},\n",
226 " {'a': (1, 4),\n",
227 " 'b': (2, 1),\n",
228 " 'c': (2, 2),\n",
229 " 'd': (2, 3),\n",
230 " 'e': (2, 4),\n",
231 " 'f': (2, 5),\n",
232 " 'g': (1, 2),\n",
233 " 'h': (3, 1),\n",
234 " 'i': (1, 1),\n",
235 " 'j': (3, 2),\n",
236 " 'k': (3, 3),\n",
237 " 'l': (3, 4),\n",
238 " 'm': (3, 5),\n",
239 " 'n': (1, 5),\n",
240 " 'o': (4, 1),\n",
241 " 'p': (4, 2),\n",
242 " 'r': (4, 3),\n",
243 " 's': (4, 4),\n",
244 " 't': (4, 5),\n",
245 " 'u': (1, 3),\n",
246 " 'v': (5, 1),\n",
247 " 'w': (5, 2),\n",
248 " 'x': (5, 3),\n",
249 " 'y': (5, 4),\n",
250 " 'z': (5, 5)},\n",
251 " {(1, 1): 'i',\n",
252 " (1, 2): 'g',\n",
253 " (1, 3): 'u',\n",
254 " (1, 4): 'a',\n",
255 " (1, 5): 'n',\n",
256 " (2, 1): 'b',\n",
257 " (2, 2): 'c',\n",
258 " (2, 3): 'd',\n",
259 " (2, 4): 'e',\n",
260 " (2, 5): 'f',\n",
261 " (3, 1): 'h',\n",
262 " (3, 2): 'j',\n",
263 " (3, 3): 'k',\n",
264 " (3, 4): 'l',\n",
265 " (3, 5): 'm',\n",
266 " (4, 1): 'o',\n",
267 " (4, 2): 'p',\n",
268 " (4, 3): 'r',\n",
269 " (4, 4): 's',\n",
270 " (4, 5): 't',\n",
271 " (5, 1): 'v',\n",
272 " (5, 2): 'w',\n",
273 " (5, 3): 'x',\n",
274 " (5, 4): 'y',\n",
275 " (5, 5): 'z'})\n"
276 ]
277 }
278 ],
279 "source": [
280 "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, {'q': 'p'}))"
281 ]
282 },
283 {
284 "cell_type": "code",
285 "execution_count": 87,
286 "metadata": {
287 "collapsed": false
288 },
289 "outputs": [],
290 "source": [
291 "# def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
292 "# letter_mapping=None, period=None):\n",
293 "# translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
294 " \n",
295 "# t_message = message.translate(translation)\n",
296 "# pairs0 = [f_grid[l] for l in t_message]\n",
297 "# items = sum([list(p) for p in pairs0], [])\n",
298 "# gap = len(message)\n",
299 "# pairs1 = [(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]\n",
300 "# return cat(r_grid[p] for p in pairs1)\n",
301 " "
302 ]
303 },
304 {
305 "cell_type": "code",
306 "execution_count": 162,
307 "metadata": {
308 "collapsed": false
309 },
310 "outputs": [],
311 "source": [
312 "def bifid_encipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
313 " letter_mapping=None, period=None, fillvalue=None):\n",
314 " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
315 " \n",
316 " t_message = message.translate(translation)\n",
317 " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
318 " if period:\n",
319 " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
320 " if len(chunked_pairs[-1]) < period and fillvalue:\n",
321 " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
322 " else:\n",
323 " chunked_pairs = [pairs0]\n",
324 " \n",
325 " pairs1 = []\n",
326 " for c in chunked_pairs:\n",
327 " items = sum(list(list(i) for i in zip(*c)), [])\n",
328 " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
329 " pairs1 += p\n",
330 " \n",
331 " return cat(r_grid[p] for p in pairs1)\n",
332 " "
333 ]
334 },
335 {
336 "cell_type": "code",
337 "execution_count": 163,
338 "metadata": {
339 "collapsed": false
340 },
341 "outputs": [
342 {
343 "data": {
344 "text/plain": [
345 "'nkklawamdkoedysipdesltirsnoesqlvvaloderbhel'"
346 ]
347 },
348 "execution_count": 163,
349 "metadata": {},
350 "output_type": "execute_result"
351 }
352 ],
353 "source": [
354 "bifid_encipher('this is a test message for the keyword decipherment', 'elephant', wrap_alphabet=KeywordWrapAlphabet.from_last)"
355 ]
356 },
357 {
358 "cell_type": "code",
359 "execution_count": 83,
360 "metadata": {
361 "collapsed": false,
362 "scrolled": true
363 },
364 "outputs": [],
365 "source": [
366 "ot, ofg, org = bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
367 ]
368 },
369 {
370 "cell_type": "code",
371 "execution_count": 85,
372 "metadata": {
373 "collapsed": false
374 },
375 "outputs": [
376 {
377 "data": {
378 "text/plain": [
379 "[(1, 1),\n",
380 " (1, 5),\n",
381 " (2, 3),\n",
382 " (1, 1),\n",
383 " (1, 4),\n",
384 " (2, 2),\n",
385 " (1, 3),\n",
386 " (4, 3),\n",
387 " (4, 3),\n",
388 " (5, 4)]"
389 ]
390 },
391 "execution_count": 85,
392 "metadata": {},
393 "output_type": "execute_result"
394 }
395 ],
396 "source": [
397 "op0 = [ofg[l] for l in \"indiacurry\"]\n",
398 "op0"
399 ]
400 },
401 {
402 "cell_type": "code",
403 "execution_count": 86,
404 "metadata": {
405 "collapsed": false
406 },
407 "outputs": [
408 {
409 "data": {
410 "text/plain": [
411 "[[(1, 1), (1, 5), (2, 3), (1, 1)],\n",
412 " [(1, 4), (2, 2), (1, 3), (4, 3)],\n",
413 " [(4, 3), (5, 4), (1, 4), (1, 4)]]"
414 ]
415 },
416 "execution_count": 86,
417 "metadata": {},
418 "output_type": "execute_result"
419 }
420 ],
421 "source": [
422 "ocp = chunks(op0, 4, fillvalue=[[ofg['a']]])\n",
423 "acc = []\n",
424 "ocp"
425 ]
426 },
427 {
428 "cell_type": "code",
429 "execution_count": 87,
430 "metadata": {
431 "collapsed": false
432 },
433 "outputs": [
434 {
435 "data": {
436 "text/plain": [
437 "[(1, 1),\n",
438 " (2, 1),\n",
439 " (1, 5),\n",
440 " (3, 1),\n",
441 " (1, 2),\n",
442 " (1, 4),\n",
443 " (4, 2),\n",
444 " (3, 3),\n",
445 " (4, 5),\n",
446 " (1, 1),\n",
447 " (3, 4),\n",
448 " (4, 4)]"
449 ]
450 },
451 "execution_count": 87,
452 "metadata": {},
453 "output_type": "execute_result"
454 }
455 ],
456 "source": [
457 "acc=[]\n",
458 "for c in ocp:\n",
459 " items = sum(list(list(i) for i in zip(*c)), [])\n",
460 " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
461 " acc += p\n",
462 "acc"
463 ]
464 },
465 {
466 "cell_type": "code",
467 "execution_count": 88,
468 "metadata": {
469 "collapsed": false
470 },
471 "outputs": [
472 {
473 "data": {
474 "text/plain": [
475 "'ibnhgaqltims'"
476 ]
477 },
478 "execution_count": 88,
479 "metadata": {},
480 "output_type": "execute_result"
481 }
482 ],
483 "source": [
484 "cat(org[p] for p in acc)"
485 ]
486 },
487 {
488 "cell_type": "code",
489 "execution_count": null,
490 "metadata": {
491 "collapsed": true
492 },
493 "outputs": [],
494 "source": []
495 },
496 {
497 "cell_type": "code",
498 "execution_count": 164,
499 "metadata": {
500 "collapsed": false
501 },
502 "outputs": [],
503 "source": [
504 "def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
505 " letter_mapping=None, period=None, fillvalue=None):\n",
506 " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
507 " \n",
508 " t_message = message.translate(translation)\n",
509 " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
510 " if period:\n",
511 " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
512 " if len(chunked_pairs[-1]) < period and fillvalue:\n",
513 " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
514 " else:\n",
515 " chunked_pairs = [pairs0]\n",
516 " \n",
517 " pairs1 = []\n",
518 " for c in chunked_pairs:\n",
519 " items = [j for i in c for j in i]\n",
520 " gap = len(c)\n",
521 " p = [(items[i], items[i+gap]) for i in range(gap)]\n",
522 " pairs1 += p\n",
523 "\n",
524 " return cat(r_grid[p] for p in pairs1) "
525 ]
526 },
527 {
528 "cell_type": "code",
529 "execution_count": 5,
530 "metadata": {
531 "collapsed": false,
532 "scrolled": true
533 },
534 "outputs": [
535 {
536 "data": {
537 "text/plain": [
538 "({106: 'i'},\n",
539 " {'a': (1, 4),\n",
540 " 'b': (2, 1),\n",
541 " 'c': (2, 2),\n",
542 " 'd': (2, 3),\n",
543 " 'e': (2, 4),\n",
544 " 'f': (2, 5),\n",
545 " 'g': (1, 2),\n",
546 " 'h': (3, 1),\n",
547 " 'i': (1, 1),\n",
548 " 'k': (3, 2),\n",
549 " 'l': (3, 3),\n",
550 " 'm': (3, 4),\n",
551 " 'n': (1, 5),\n",
552 " 'o': (3, 5),\n",
553 " 'p': (4, 1),\n",
554 " 'q': (4, 2),\n",
555 " 'r': (4, 3),\n",
556 " 's': (4, 4),\n",
557 " 't': (4, 5),\n",
558 " 'u': (1, 3),\n",
559 " 'v': (5, 1),\n",
560 " 'w': (5, 2),\n",
561 " 'x': (5, 3),\n",
562 " 'y': (5, 4),\n",
563 " 'z': (5, 5)},\n",
564 " {(1, 1): 'i',\n",
565 " (1, 2): 'g',\n",
566 " (1, 3): 'u',\n",
567 " (1, 4): 'a',\n",
568 " (1, 5): 'n',\n",
569 " (2, 1): 'b',\n",
570 " (2, 2): 'c',\n",
571 " (2, 3): 'd',\n",
572 " (2, 4): 'e',\n",
573 " (2, 5): 'f',\n",
574 " (3, 1): 'h',\n",
575 " (3, 2): 'k',\n",
576 " (3, 3): 'l',\n",
577 " (3, 4): 'm',\n",
578 " (3, 5): 'o',\n",
579 " (4, 1): 'p',\n",
580 " (4, 2): 'q',\n",
581 " (4, 3): 'r',\n",
582 " (4, 4): 's',\n",
583 " (4, 5): 't',\n",
584 " (5, 1): 'v',\n",
585 " (5, 2): 'w',\n",
586 " (5, 3): 'x',\n",
587 " (5, 4): 'y',\n",
588 " (5, 5): 'z'})"
589 ]
590 },
591 "execution_count": 5,
592 "metadata": {},
593 "output_type": "execute_result"
594 }
595 ],
596 "source": [
597 "bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
598 ]
599 },
600 {
601 "cell_type": "code",
602 "execution_count": 139,
603 "metadata": {
604 "collapsed": false
605 },
606 "outputs": [
607 {
608 "data": {
609 "text/plain": [
610 "'ibidonhprm'"
611 ]
612 },
613 "execution_count": 139,
614 "metadata": {},
615 "output_type": "execute_result"
616 }
617 ],
618 "source": [
619 "bifid_encipher(\"indiajelly\", 'iguana')"
620 ]
621 },
622 {
623 "cell_type": "code",
624 "execution_count": 166,
625 "metadata": {
626 "collapsed": false
627 },
628 "outputs": [
629 {
630 "data": {
631 "text/plain": [
632 "'ibidonhprm'"
633 ]
634 },
635 "execution_count": 166,
636 "metadata": {},
637 "output_type": "execute_result"
638 }
639 ],
640 "source": [
641 "bifid_encipher(\"indiajelly\", 'iguana', period=0)"
642 ]
643 },
644 {
645 "cell_type": "code",
646 "execution_count": 140,
647 "metadata": {
648 "collapsed": false
649 },
650 "outputs": [
651 {
652 "data": {
653 "text/plain": [
654 "'indiaielly'"
655 ]
656 },
657 "execution_count": 140,
658 "metadata": {},
659 "output_type": "execute_result"
660 }
661 ],
662 "source": [
663 "bifid_decipher('ibidonhprm', 'iguana')"
664 ]
665 },
666 {
667 "cell_type": "code",
668 "execution_count": 137,
669 "metadata": {
670 "collapsed": false
671 },
672 "outputs": [
673 {
674 "data": {
675 "text/plain": [
676 "'ibnhgaqltm'"
677 ]
678 },
679 "execution_count": 137,
680 "metadata": {},
681 "output_type": "execute_result"
682 }
683 ],
684 "source": [
685 "bifid_encipher(\"indiacurry\", 'iguana', period=4)"
686 ]
687 },
688 {
689 "cell_type": "code",
690 "execution_count": 138,
691 "metadata": {
692 "collapsed": false
693 },
694 "outputs": [
695 {
696 "data": {
697 "text/plain": [
698 "'indiacurry'"
699 ]
700 },
701 "execution_count": 138,
702 "metadata": {},
703 "output_type": "execute_result"
704 }
705 ],
706 "source": [
707 "bifid_decipher(\"ibnhgaqltm\", 'iguana', period=4)"
708 ]
709 },
710 {
711 "cell_type": "code",
712 "execution_count": 144,
713 "metadata": {
714 "collapsed": false
715 },
716 "outputs": [
717 {
718 "data": {
719 "text/plain": [
720 "'ibnhgaqltzml'"
721 ]
722 },
723 "execution_count": 144,
724 "metadata": {},
725 "output_type": "execute_result"
726 }
727 ],
728 "source": [
729 "bifid_encipher(\"indiacurry\", 'iguana', period=4, fillvalue='x')"
730 ]
731 },
732 {
733 "cell_type": "code",
734 "execution_count": 146,
735 "metadata": {
736 "collapsed": false
737 },
738 "outputs": [
739 {
740 "data": {
741 "text/plain": [
742 "'indiacurryxx'"
743 ]
744 },
745 "execution_count": 146,
746 "metadata": {},
747 "output_type": "execute_result"
748 }
749 ],
750 "source": [
751 "bifid_decipher(\"ibnhgaqltzml\", 'iguana', period=4)"
752 ]
753 },
754 {
755 "cell_type": "code",
756 "execution_count": 101,
757 "metadata": {
758 "collapsed": true
759 },
760 "outputs": [],
761 "source": [
762 "p0 = [(1, 1), (2, 1), (1, 5), (3, 1)]"
763 ]
764 },
765 {
766 "cell_type": "code",
767 "execution_count": 103,
768 "metadata": {
769 "collapsed": false,
770 "scrolled": true
771 },
772 "outputs": [
773 {
774 "data": {
775 "text/plain": [
776 "[1, 1, 2, 1, 1, 5, 3, 1]"
777 ]
778 },
779 "execution_count": 103,
780 "metadata": {},
781 "output_type": "execute_result"
782 }
783 ],
784 "source": [
785 "t0 = [j for i in p0 for j in i]\n",
786 "t0"
787 ]
788 },
789 {
790 "cell_type": "code",
791 "execution_count": 104,
792 "metadata": {
793 "collapsed": false
794 },
795 "outputs": [
796 {
797 "data": {
798 "text/plain": [
799 "[(1, 1), (1, 5), (2, 3), (1, 1)]"
800 ]
801 },
802 "execution_count": 104,
803 "metadata": {},
804 "output_type": "execute_result"
805 }
806 ],
807 "source": [
808 "[(t0[i], t0[i+4]) for i in range(4)]"
809 ]
810 },
811 {
812 "cell_type": "code",
813 "execution_count": 130,
814 "metadata": {
815 "collapsed": false
816 },
817 "outputs": [
818 {
819 "data": {
820 "text/plain": [
821 "'martinwehavemadeadreadfulmistakeandihavebeentooslowtoadmitthattomyselfihavehadavisitfromthewomanfromthesyndicateandiconfrontedheraboutthesourceofthetemplatessheconfirmedmyworstfearsandnowiwanttocrawlawayanddiewhathavewedoneoursoftwarehasledtosomuchsufferingwhenitwasdesignedtodotheoppositeiaskedherhowthecabinetofficecouldpossiblyhaveauthorisedthisandshelaughedandexplainedthatthesyndicatenolongerworkedforthebritishgovernmentcallitprivateenterpriseshesaidwehavealwaysbeengoodatthatmyhorrormusthavebeenwrittenallovermyfaceshedidntseemsurprisedatmyreactionbutequallyshedidnttakeitwellandcivilitywasabandonediaskedherhowitcouldbelegalletalonemoraltodowhattheyproposedandheranswerwasthatitwasnecessaryisaidwewouldnthelpthemandshesaiditwasnecessarythatwedidisaidiwouldntbeabletofacemyfamilyandfriendsifwecooperatedandshesaidiwouldnthavetoworryaboutthatforlongonewayoranotherthepdssyndicateweregoingtomakesurewebothdisappearedlookingbackicanseethatfromthestartthiswholethinghasactedtodrawusintoitscentreandnowiamattheeventhorizonalmostunabletoescapeitspullbutithinkwehaveonelastchanceiamsureshewillbevisitingyouaswellshethinkswehavenochoicebutithinkachoiceisallwehavewhateveryoudoholdoutforbettertermsshehastobelievethatyouareonsideandmotivatedbygreedsothatshewontworryaboutanyqualmsyoumighthaveconvinceherthatyouwillconvincemetocooperatetellherthatyouthinkyoushouldworkfromthecollectiveinosloandthatyouwantpaymentviathebankinswitzerlandigottheimpressionthatmoneyisnotaproblemwithmoneyinaswissbankandtheexpertiseandconnectivityaffordedbythecollectiveithinkwehaveachancetoescapeandtotrytostopthemperhapswewillsurvivethisperhapswecanbringthemdown'"
822 ]
823 },
824 "execution_count": 130,
825 "metadata": {},
826 "output_type": "execute_result"
827 }
828 ],
829 "source": [
830 "bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4, fillvalue=None)"
831 ]
832 },
833 {
834 "cell_type": "code",
835 "execution_count": 147,
836 "metadata": {
837 "collapsed": false
838 },
839 "outputs": [
840 {
841 "data": {
842 "text/plain": [
843 "'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'"
844 ]
845 },
846 "execution_count": 147,
847 "metadata": {},
848 "output_type": "execute_result"
849 }
850 ],
851 "source": [
852 "wcat(segment(bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4)))"
853 ]
854 },
855 {
856 "cell_type": "code",
857 "execution_count": null,
858 "metadata": {
859 "collapsed": true
860 },
861 "outputs": [],
862 "source": []
863 },
864 {
865 "cell_type": "code",
866 "execution_count": null,
867 "metadata": {
868 "collapsed": true
869 },
870 "outputs": [],
871 "source": []
872 },
873 {
874 "cell_type": "code",
875 "execution_count": null,
876 "metadata": {
877 "collapsed": true
878 },
879 "outputs": [],
880 "source": []
881 },
882 {
883 "cell_type": "code",
884 "execution_count": null,
885 "metadata": {
886 "collapsed": true
887 },
888 "outputs": [],
889 "source": []
890 },
891 {
892 "cell_type": "code",
893 "execution_count": null,
894 "metadata": {
895 "collapsed": true
896 },
897 "outputs": [],
898 "source": []
899 },
900 {
901 "cell_type": "code",
902 "execution_count": 49,
903 "metadata": {
904 "collapsed": true
905 },
906 "outputs": [],
907 "source": [
908 "p0 = [(2, 1), (3, 3), (3, 3), (5, 1), (1, 4)]"
909 ]
910 },
911 {
912 "cell_type": "code",
913 "execution_count": 54,
914 "metadata": {
915 "collapsed": false
916 },
917 "outputs": [
918 {
919 "data": {
920 "text/plain": [
921 "[2, 1, 3, 3, 3, 3, 5, 1, 1, 4]"
922 ]
923 },
924 "execution_count": 54,
925 "metadata": {},
926 "output_type": "execute_result"
927 }
928 ],
929 "source": [
930 "items = sum([list(p) for p in p0], [])\n",
931 "items"
932 ]
933 },
934 {
935 "cell_type": "code",
936 "execution_count": 55,
937 "metadata": {
938 "collapsed": false
939 },
940 "outputs": [
941 {
942 "data": {
943 "text/plain": [
944 "[(2, 3), (1, 5), (3, 1), (3, 1), (3, 4)]"
945 ]
946 },
947 "execution_count": 55,
948 "metadata": {},
949 "output_type": "execute_result"
950 }
951 ],
952 "source": [
953 "gap=5\n",
954 "[(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]"
955 ]
956 },
957 {
958 "cell_type": "code",
959 "execution_count": 91,
960 "metadata": {
961 "collapsed": true
962 },
963 "outputs": [],
964 "source": [
965 "c7bs = sanitise(c7b)"
966 ]
967 },
968 {
969 "cell_type": "code",
970 "execution_count": 115,
971 "metadata": {
972 "collapsed": true
973 },
974 "outputs": [],
975 "source": [
976 "def bifid_break_mp(message, wordlist=keywords, fitness=Pletters,\n",
977 " number_of_solutions=1, chunksize=500):\n",
978 " \"\"\"Breaks a keyword substitution cipher using a dictionary and\n",
979 " frequency analysis\n",
980 "\n",
981 " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
982 " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
983 " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
984 " (('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...)\n",
985 " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
986 " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
987 " wordlist=['cat', 'elephant', 'kangaroo'], \\\n",
988 " number_of_solutions=2) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n",
989 " [(('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...), \n",
990 " (('elephant', <KeywordWrapAlphabet.from_largest: 3>), -52.834575011...)]\n",
991 " \"\"\"\n",
992 " with Pool() as pool:\n",
993 " helper_args = [(message, word, wrap, fitness)\n",
994 " for word in wordlist\n",
995 " for wrap in KeywordWrapAlphabet]\n",
996 " # Gotcha: the helper function here needs to be defined at the top level\n",
997 " # (limitation of Pool.starmap)\n",
998 " breaks = pool.starmap(bifid_break_worker, helper_args, chunksize)\n",
999 " if number_of_solutions == 1:\n",
1000 " return max(breaks, key=lambda k: k[1])\n",
1001 " else:\n",
1002 " return sorted(breaks, key=lambda k: k[1], reverse=True)[:number_of_solutions]\n"
1003 ]
1004 },
1005 {
1006 "cell_type": "code",
1007 "execution_count": 116,
1008 "metadata": {
1009 "collapsed": true
1010 },
1011 "outputs": [],
1012 "source": [
1013 "def bifid_break_worker(message, keyword, wrap_alphabet, fitness):\n",
1014 " plaintext = bifid_decipher(message, keyword, wrap_alphabet)\n",
1015 " fit = fitness(plaintext)\n",
1016 " logger.debug('Keyword break attempt using key {0} (wrap={1}) gives fit of '\n",
1017 " '{2} and decrypt starting: {3}'.format(keyword, \n",
1018 " wrap_alphabet, fit, sanitise(plaintext)[:50]))\n",
1019 " return (keyword, wrap_alphabet), fit"
1020 ]
1021 },
1022 {
1023 "cell_type": "code",
1024 "execution_count": 107,
1025 "metadata": {
1026 "collapsed": false
1027 },
1028 "outputs": [
1029 {
1030 "data": {
1031 "text/plain": [
1032 "'enamokkneogiyegrkcuzbgsydkoqoswiwvtgbolrkfuzbgsyskdqusgnttqetuonyegyfkbsteqeycgbudbvqadcepgqrsbbeaeoqilrqcsosfcdyrbztiuirvqrtcmesbkudboeytksofknyegrambmctvxeogttfggemokopiqwinutqhdtoftsgsathnemlteprmrqbstdolsaklrueucsvncyhgqqcsfqlutsdxzthnfuvotauhnyegosloeogwrrqclelbonknefqkrkofvoqhxttvrimhyttvyqosrlegqtbeyroeuegbtnqkeecgqepblclvutouaehtoekceqgpeobwaohndxlstmvnvalttupquvoieruortugrhfsyqosnsqcesrvhtcrarvqnshkudbistnbwuootauhtqefiolctxqoqhdsmrneettrtberyybtnqblqxgrtrveqyfoboxwaehwlplqrcbiowhirimheyotqcciorhitvdaqkdurimhtheslelwxuooneagedooqlfibrlfhesrpxtgrrbkarhrxqobtogwaehwrimheyotlviqpesoyfkbsteqoviiynstnvhltfgarqostqdfotktpfhlrnadyegrtencsrtltknqffyqsnietwrixhogeqgsooihkiuhtwtonotknenquarhtnerycgicadbschhthlbeurbzpmqkqbsoebweprtepkhtsqhrslbrrefycoisnkumuedqrseqtshftqvftvkntlgbyqbyqosyotbucvtetvqoawhtgniucoadpiqomkeysgcyroeuegbefwimtedcpqcyogakzhbnepcztbqoviiotcnguiocdaipkqbkebwyqosepuqsrecnfsvedoipoqkmyegsqdsaogktgniurofkwfldeoupsqerncsfevoyqosxcoueswnfoqkspkbnyrheuqxotktarhasoiofnqhtokluoqivslbqhbcveqberoaboskskcsfslctsgkapbqftvuiilvcsbkaqlbrrubwtgtnkdboskylzlqqyetqekleuebrsyspnbrcfqspstdntrndsichescznbprqealulhteroctydoocwanhtprnocothnypoqysosniltodcsfyvvolwaehwdpiqoskedwonrtentycobwanelolftbnneksonwlhrsqcqqcqrsopeckrcountigqtldycoisnkuotktanhetwklvshfspkboxkqaolkmyegdqossdcorqoszoowaohabmityghiurocczicttqkifbboekyorhehedkxrobesooztmbqnsbtsqcnkgqnxcorruhokkaergezpctbpdnntqqshcqaehrfyvenwqtttbgsrcfvqasarhfksbkufvvawlacteqtfnvctvhspkqwyocnrtormzdnckouekbomkttarlptmroyketcbrusoeqystofbqoskctenquekbkybgtfrbktbxsqesswgeysggrqfsswgeedoovxaiqvdabaginnrptyqoqesomudleoylstoqtodcoawhkybgeukqdgogzxeiexrinpchoawheewgepth'"
1033 ]
1034 },
1035 "execution_count": 107,
1036 "metadata": {},
1037 "output_type": "execute_result"
1038 }
1039 ],
1040 "source": [
1041 "c7bs = sanitise(c7b)\n",
1042 "c7br = cat(reversed(c7bs))\n",
1043 "c7br"
1044 ]
1045 },
1046 {
1047 "cell_type": "code",
1048 "execution_count": 148,
1049 "metadata": {
1050 "collapsed": false
1051 },
1052 "outputs": [
1053 {
1054 "data": {
1055 "text/plain": [
1056 "(('ligo', <KeywordWrapAlphabet.from_a: 1>), -2505.924490942904)"
1057 ]
1058 },
1059 "execution_count": 148,
1060 "metadata": {},
1061 "output_type": "execute_result"
1062 }
1063 ],
1064 "source": [
1065 "bifid_break_mp(c7bs, wordlist=['gravity', 'ligo'])"
1066 ]
1067 },
1068 {
1069 "cell_type": "code",
1070 "execution_count": 102,
1071 "metadata": {
1072 "collapsed": false
1073 },
1074 "outputs": [
1075 {
1076 "data": {
1077 "text/plain": [
1078 "'ksotagstmczesqstldwfasoehepicltaryruvgstiwbtylwzlanehrdmthhlqzeohpsdytllgdxfcetbiislqetoukobnterkoyonsetkodhtymxuefpdtnhnsulwnnurhiotctcrwhprbssrdblxanlrxadxgxatetsegdoeuhawberbaswolpqkrkpfcxufohcyefaeabqtkbrykbdonghsbaodvongcfdvngmeslhetnytkocenotirklsatenkdeeyoentbryuoleqoefcuxpqbsirotbogkvtqbrqgyoqamkninrfottolgmynbsekmeouwueklcpqrekyylvronsntcotrrctdvoyfthkgalscldypooicxrtpdyttohfoqtprrbgtwepsycwpswuylkedbiglsylbctcfecisumvrbyparteagabdqouuttohvbtcdtxczusxrtleburbtkapmsfctmokootcoibkclbetoaralxzdnlpanenadkhhgtsldnyrupnqsravhtpohmplgtaacuhfpttdebroaqhedgvooyyneoebrfudfodroyklhsheqheeqhdinusytmhdqqedsbbdzcylgukonttacivvvcrprteautwrxhdmczntnixhzbeasmboscsyeqdtsxxeiodohrnofaidlbabrobumelkaeuvnlylglqnfpeqklhwlqeselhameievlbeawrlnllyetoeolencrduoghqqoeqyhlqidrrvndrrwnfhmottqllpayunortyoeariuhharstrhnsfaaoqlipqkohcrnldicnlshnysnrtdbiggeonatcseqosygonehtdutacbzdbstdcrzttntrbtunrotcuewfslftkgdruetlrxrgbmvegfsqieybgqtfxaxrvqbybcaibhoeoolnpxnrdatsspxotloerkwotcheutoerrufnprncktohsqarexdccnbtbekxtqtcrtbaqsottmbltovlurbeoolrtpksbtpyvrasrbtkfricyeremtpaqunucemnterrmdpoldyaicofeoppgepxtdaioeesqqysthohkeotktnstxntgtmhqvyhoythkeanebdshlmtrnqhrunweeeozctiofegqolrfmmdbdacryrmqrypwuwvcntdyqksdamrsglgisanncrmoerfveprpkgbagkerobderbnbatdnedugenxarredlduheegqbrycawnknbnylomloetokdolqreyuecvufbrpsmsptadqthkuotdvknhuyetldctwotidfglrgspmhokusbvtpvbeietnxqbirwhspqetmyotewabodyfppaoacoequgsrrgtyqfsnegmtfvzelmfwosrutwpvnamanthhgcnepsepeguldrhaenwolwhhohnsrlpxnsdhenvadcbyqicaboptfaoknvcmeoerqbtlyovbbddommednhlmrlcyaeflratepytylrnpcantuepwpxxanfthsdnowzirihfqqcedlewwhkcelinfwniiohclardlbqqokzrwvdswbufemcsqqveqnbruynipgrbaytsqkkkyodugayche'"
1079 ]
1080 },
1081 "execution_count": 102,
1082 "metadata": {},
1083 "output_type": "execute_result"
1084 }
1085 ],
1086 "source": [
1087 "bifid_decipher(c7bs, 'capris', KeywordWrapAlphabet.from_a )"
1088 ]
1089 },
1090 {
1091 "cell_type": "code",
1092 "execution_count": 104,
1093 "metadata": {
1094 "collapsed": false
1095 },
1096 "outputs": [
1097 {
1098 "data": {
1099 "text/plain": [
1100 "'dnrobchyoikvkwtucnsiganmyoanfatckweqpwxwehfdpoxqdvtworugsnpsxanmycvirrgedmuihpienwfnpwyzdffaqsxsoutvbvqlovoplenqrnktqlernruwptiswodnhaxomrtwbmpunnbnolcrvsasmcblsvawegytshecczeperucfeqlrcosbfdhdkcaeipnsligmsnapleqpoutoqgtcobyzorcehvvkkrhoxngkavnolkcrncshwetpocgnysxewemonekysintysuqrlntykpvsckgenbecfybfmycsrtzrxfckstgbirtnmnhdhcetfvuttwptpbigplyctfisoxttslhhbvtnotminnusfcqobdtnlhnpbnhxhpirckoatchwiaofaloprrbyonlouscekwlsnboyciswcoosyirodpwsgghcqhofeuosmtqfhqsztrsscwxfzwrnhhnphtpvwnurikaeoxgftoyodrmaqnosloukciskmbycicidsgeofsbrfodhsrtskwtpbtgnsmnyncrvsrhtwrsiolhlylrnntvrkenffvgfypknntxryqqgonspndmocrhcpfrnbgerwqncuiciqverfealtrnoomnwdnenepldpgatsbbffsaogoynownnotoxbeckllrnonbknycsensfleqbctonegzaccsifmnuezvlfqsurrgwviiuwrdcgoininoyseugowzkpntfctreowotnetkswlctahmgrpoypohsnoqnqooogboctspteznllttcurbcbiewnslipsshliwsybvalnlosrrtpcfzepwsnonktceovhhrnqfeilrkmsrlseoinyfsfunulffevuofwrenqbrettkrtkbnkelciibvsysafkrisombfmsqgwlfbnekikdyreipgzshnonclsrzgyceeanhlvcluucfsomraasehigprxbmfiftdnhgxhfbnzopntrsgcudoigstteflifktxiewbaqltwevuznctfgxhgtihgeruomubtgsvaxgoysnontudtebmabnbvsnsrqffslnigcfnemqgnhfckqpncoewfrnmbictedfkwaateghravmulprcftrqngazecectflxcicnhhwllbrwpoiitgqvknmogoeckpsqtvofttwbhpsntarshokvnigrlypropqiitoznlghoknmifdedtapmpisprrsfewfnqttitvnkoaltfmfqicnsaedyxuaklctantctroesoorbkkmpktnwnoulfnmrvougqstqkfdtttvarerhylgfoimeanomleupotornghfryklsyfgtnxdnnsttsoitriyisennougsveatellinkpetkaxodulaihaoebevagqodofghminllhpelcnszrbagvzsclxphrvplbhossnckahwaeroakctnekodiwgfinquogmgraqpgqafienectgnwoeusnilosiptysyfxuydrdxsgtcoucislntosflhttnogzrlntrwkrxiokklphbagvsufdlxpuhpnoqwuukirefqweuxtrtbtnnwrshqneawdghirfaturhpwesptebb'"
1101 ]
1102 },
1103 "execution_count": 104,
1104 "metadata": {},
1105 "output_type": "execute_result"
1106 }
1107 ],
1108 "source": [
1109 "bifid_decipher(c7br, 'trinket', KeywordWrapAlphabet.from_a)"
1110 ]
1111 },
1112 {
1113 "cell_type": "code",
1114 "execution_count": null,
1115 "metadata": {
1116 "collapsed": true
1117 },
1118 "outputs": [],
1119 "source": []
1120 }
1121 ],
1122 "metadata": {
1123 "kernelspec": {
1124 "display_name": "Python 3",
1125 "language": "python",
1126 "name": "python3"
1127 },
1128 "language_info": {
1129 "codemirror_mode": {
1130 "name": "ipython",
1131 "version": 3
1132 },
1133 "file_extension": ".py",
1134 "mimetype": "text/x-python",
1135 "name": "python",
1136 "nbconvert_exporter": "python",
1137 "pygments_lexer": "ipython3",
1138 "version": "3.5.2"
1139 }
1140 },
1141 "nbformat": 4,
1142 "nbformat_minor": 0
1143 }