ab1b457c441d51cb55d4e6a5d2385a37379fc6c2
[cipher-training.git] / bombe.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 797,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "import string\n",
12 "import collections\n",
13 "import multiprocessing\n",
14 "import itertools\n",
15 "from enigma import *"
16 ]
17 },
18 {
19 "cell_type": "code",
20 "execution_count": 798,
21 "metadata": {
22 "collapsed": true
23 },
24 "outputs": [],
25 "source": [
26 "# wheel_i_spec = 'ekmflgdqvzntowyhxuspaibrcj'\n",
27 "# wheel_ii_spec = 'ajdksiruxblhwtmcqgznpyfvoe'\n",
28 "# wheel_iii_spec = 'bdfhjlcprtxvznyeiwgakmusqo'\n",
29 "# wheel_iv_spec = 'esovpzjayquirhxlnftgkdcmwb'\n",
30 "# wheel_v_spec = 'vzbrgityupsdnhlxawmjqofeck'\n",
31 "# wheel_vi_spec = 'jpgvoumfyqbenhzrdkasxlictw'\n",
32 "# wheel_vii_spec = 'nzjhgrcxmyswboufaivlpekqdt'\n",
33 "# wheel_viii_spec = 'fkqhtlxocbjspdzramewniuygv'\n",
34 "# beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos'\n",
35 "# gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd'\n",
36 "\n",
37 "# wheel_i_pegs = ['q']\n",
38 "# wheel_ii_pegs = ['e']\n",
39 "# wheel_iii_pegs = ['v']\n",
40 "# wheel_iv_pegs = ['j']\n",
41 "# wheel_v_pegs = ['z']\n",
42 "# wheel_vi_pegs = ['z', 'm']\n",
43 "# wheel_vii_pegs = ['z', 'm']\n",
44 "# wheel_viii_pegs = ['z', 'm']\n",
45 "\n",
46 "# reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw'\n",
47 "# reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su'"
48 ]
49 },
50 {
51 "cell_type": "code",
52 "execution_count": 799,
53 "metadata": {
54 "collapsed": true
55 },
56 "outputs": [],
57 "source": [
58 "class Bank(object):\n",
59 " def __init__(self):\n",
60 " self.signals = dict(zip(string.ascii_lowercase, [False]*len(string.ascii_lowercase)))"
61 ]
62 },
63 {
64 "cell_type": "code",
65 "execution_count": 800,
66 "metadata": {
67 "collapsed": false
68 },
69 "outputs": [
70 {
71 "data": {
72 "text/plain": [
73 "{'a': False,\n",
74 " 'b': False,\n",
75 " 'c': False,\n",
76 " 'd': False,\n",
77 " 'e': False,\n",
78 " 'f': False,\n",
79 " 'g': False,\n",
80 " 'h': False,\n",
81 " 'i': False,\n",
82 " 'j': False,\n",
83 " 'k': False,\n",
84 " 'l': False,\n",
85 " 'm': False,\n",
86 " 'n': False,\n",
87 " 'o': False,\n",
88 " 'p': False,\n",
89 " 'q': False,\n",
90 " 'r': False,\n",
91 " 's': False,\n",
92 " 't': False,\n",
93 " 'u': False,\n",
94 " 'v': False,\n",
95 " 'w': False,\n",
96 " 'x': False,\n",
97 " 'y': False,\n",
98 " 'z': False}"
99 ]
100 },
101 "execution_count": 800,
102 "metadata": {},
103 "output_type": "execute_result"
104 }
105 ],
106 "source": [
107 "c1 = Bank()\n",
108 "c1.signals"
109 ]
110 },
111 {
112 "cell_type": "code",
113 "execution_count": 801,
114 "metadata": {
115 "collapsed": true
116 },
117 "outputs": [],
118 "source": [
119 "Signal = collections.namedtuple('Signal', ['bank', 'wire'])\n",
120 "Connection = collections.namedtuple('Connection', ['banks', 'scrambler'])\n",
121 "MenuItem = collections.namedtuple('MenuIem', ['before', 'after', 'number'])"
122 ]
123 },
124 {
125 "cell_type": "code",
126 "execution_count": 802,
127 "metadata": {
128 "collapsed": true
129 },
130 "outputs": [],
131 "source": [
132 "class Scrambler(object):\n",
133 " def __init__(self, wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec,\n",
134 " wheel1_pos='a', wheel2_pos='a', wheel3_pos='a'):\n",
135 " self.wheel1 = SimpleWheel(wheel1_spec, position=wheel1_pos)\n",
136 " self.wheel2 = SimpleWheel(wheel2_spec, position=wheel2_pos)\n",
137 " self.wheel3 = SimpleWheel(wheel3_spec, position=wheel3_pos)\n",
138 " self.reflector = Reflector(reflector_spec)\n",
139 " \n",
140 " def __getattribute__(self, name):\n",
141 " if name=='wheel_positions':\n",
142 " return self.wheel1.position, self.wheel2.position, self.wheel3.position \n",
143 " elif name=='wheel_positions_l':\n",
144 " return self.wheel1.position_l, self.wheel2.position_l, self.wheel3.position_l \n",
145 " else:\n",
146 " return object.__getattribute__(self, name)\n",
147 " \n",
148 " def advance(self, wheel1=False, wheel2=False, wheel3=True):\n",
149 " if wheel1: self.wheel1.advance()\n",
150 " if wheel2: self.wheel2.advance()\n",
151 " if wheel3: self.wheel3.advance()\n",
152 " \n",
153 " def lookup(self, letter):\n",
154 " a = self.wheel3.forward(letter)\n",
155 " b = self.wheel2.forward(a)\n",
156 " c = self.wheel1.forward(b)\n",
157 " d = self.reflector.forward(c)\n",
158 " e = self.wheel1.backward(d)\n",
159 " f = self.wheel2.backward(e)\n",
160 " g = self.wheel3.backward(f)\n",
161 " return g\n",
162 " \n",
163 " def set_positions(self, wheel1_pos, wheel2_pos, wheel3_pos):\n",
164 " self.wheel1.set_position(wheel1_pos)\n",
165 " self.wheel2.set_position(wheel2_pos)\n",
166 " self.wheel3.set_position(wheel3_pos) "
167 ]
168 },
169 {
170 "cell_type": "code",
171 "execution_count": 803,
172 "metadata": {
173 "collapsed": false
174 },
175 "outputs": [],
176 "source": [
177 "class Bombe(object):\n",
178 " def __init__(self, wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec,\n",
179 " menu=None, start_signal=None, use_diagonal_board=True, verify_plugboard=True):\n",
180 " self.connections = []\n",
181 " self.wheel1_spec = wheel1_spec\n",
182 " self.wheel2_spec = wheel2_spec\n",
183 " self.wheel3_spec = wheel3_spec\n",
184 " self.reflector_spec = reflector_spec\n",
185 " if menu:\n",
186 " self.read_menu(menu)\n",
187 " if start_signal:\n",
188 " self.test_start = start_signal\n",
189 " self.use_diagonal_board = use_diagonal_board\n",
190 " self.verify_plugboard = verify_plugboard\n",
191 " \n",
192 " def __getattribute__(self, name):\n",
193 " if name=='wheel_positions':\n",
194 " return self.connections[0].scrambler.wheel_positions\n",
195 " elif name=='wheel_positions_l':\n",
196 " return self.connections[0].scrambler.wheel_positions_l\n",
197 " else:\n",
198 " return object.__getattribute__(self, name)\n",
199 " \n",
200 " def __call__(self, start_positions):\n",
201 " return start_positions, self.test(start_positions=start_positions, \n",
202 " use_diagonal_board=self.use_diagonal_board,\n",
203 " verify_plugboard=self.verify_plugboard)\n",
204 " \n",
205 " def add_connection(self, bank_before, bank_after, scrambler):\n",
206 " self.connections += [Connection([bank_before, bank_after], scrambler)]\n",
207 " \n",
208 " def read_menu(self, menu):\n",
209 " for item in menu:\n",
210 " scrambler = Scrambler(self.wheel1_spec, self.wheel2_spec, self.wheel3_spec,\n",
211 " self.reflector_spec,\n",
212 " wheel3_pos=unpos(item.number - 1))\n",
213 " self.add_connection(item.before, item.after, scrambler)\n",
214 " most_common_letter = (collections.Counter(m.before for m in menu) + \\\n",
215 " collections.Counter(m.after for m in menu)).most_common(1)[0][0]\n",
216 " self.test_start = Signal(most_common_letter, most_common_letter)\n",
217 " \n",
218 " def set_positions(self, wheel1_pos, wheel2_pos, wheel3_pos):\n",
219 " for i, c in enumerate(self.connections):\n",
220 " c.scrambler.set_positions(wheel1_pos, wheel2_pos, unpos(pos(wheel3_pos) + i))\n",
221 " \n",
222 " def test(self, initial_signal=None, start_positions=None, use_diagonal_board=True,\n",
223 " verify_plugboard=True):\n",
224 " self.banks = {label: \n",
225 " dict(zip(string.ascii_lowercase, [False]*len(string.ascii_lowercase)))\n",
226 " for label in string.ascii_lowercase}\n",
227 " if start_positions:\n",
228 " self.set_positions(*start_positions)\n",
229 " if not initial_signal:\n",
230 " initial_signal = self.test_start\n",
231 " self.pending = [initial_signal]\n",
232 " self.propagate(use_diagonal_board)\n",
233 " live_wire_count = len([self.banks[self.test_start.bank][w] \n",
234 " for w in self.banks[self.test_start.bank] \n",
235 " if self.banks[self.test_start.bank][w]])\n",
236 " if live_wire_count < 26:\n",
237 " if verify_plugboard:\n",
238 " possibles = self.possible_plugboards()\n",
239 " return all(s0.isdisjoint(s1) for s0 in possibles for s1 in possibles if s0 != s1)\n",
240 " else:\n",
241 " return True\n",
242 " else:\n",
243 " return False\n",
244 " \n",
245 " def propagate(self, use_diagonal_board):\n",
246 " while self.pending:\n",
247 " current = self.pending[0]\n",
248 " # print(\"processing\", current)\n",
249 " self.pending = self.pending[1:]\n",
250 " if not self.banks[current.bank][current.wire]:\n",
251 " self.banks[current.bank][current.wire] = True\n",
252 " if use_diagonal_board:\n",
253 " self.pending += [Signal(current.wire, current.bank)]\n",
254 " for c in self.connections:\n",
255 " if current.bank in c.banks:\n",
256 " other_bank = [b for b in c.banks if b != current.bank][0]\n",
257 " other_wire = c.scrambler.lookup(current.wire)\n",
258 " # print(\" adding\", other_bank, other_wire, \"because\", c.banks)\n",
259 " self.pending += [Signal(other_bank, other_wire)]\n",
260 " \n",
261 " def run(self, run_start=None, wheel1_pos='a', wheel2_pos='a', wheel3_pos='a', use_diagonal_board=True):\n",
262 " if not run_start:\n",
263 " run_start = self.test_start\n",
264 " self.solutions = []\n",
265 " self.set_positions(wheel1_pos, wheel2_pos, wheel3_pos)\n",
266 " for run_index in range(26*26*26):\n",
267 " if self.test(initial_signal=run_start, use_diagonal_board=use_diagonal_board):\n",
268 " self.solutions += [self.connections[0].scrambler.wheel_positions_l]\n",
269 " advance3 = True\n",
270 " advance2 = False\n",
271 " advance1 = False\n",
272 " if (run_index + 1) % 26 == 0: advance2 = True\n",
273 " if (run_index + 1) % (26*26) == 0: advance1 = True\n",
274 " for c in self.connections:\n",
275 " c.scrambler.advance(advance1, advance2, advance3)\n",
276 " return self.solutions\n",
277 " \n",
278 " def possible_plugboards(self):\n",
279 " possibles = set()\n",
280 " for b in self.banks:\n",
281 " active = [w for w in self.banks[b] if self.banks[b][w]]\n",
282 " inactive = [w for w in self.banks[b] if not self.banks[b][w]]\n",
283 " if len(active) == 1:\n",
284 " possibles = possibles.union({frozenset((b, active[0]))})\n",
285 " if len(inactive) == 1:\n",
286 " possibles = possibles.union({frozenset((b, inactive[0]))})\n",
287 " return possibles"
288 ]
289 },
290 {
291 "cell_type": "code",
292 "execution_count": 804,
293 "metadata": {
294 "collapsed": false
295 },
296 "outputs": [],
297 "source": [
298 "bombe = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec)\n",
299 "# len(bombe.banks), bombe.banks['a'] == bombe.banks['b']"
300 ]
301 },
302 {
303 "cell_type": "code",
304 "execution_count": 805,
305 "metadata": {
306 "collapsed": true
307 },
308 "outputs": [],
309 "source": [
310 "test_enigma = Enigma(reflector_b_spec, \n",
311 " wheel_i_spec, wheel_i_pegs,\n",
312 " wheel_ii_spec, wheel_ii_pegs,\n",
313 " wheel_iii_spec, wheel_iii_pegs,\n",
314 " 1, 1, 1,\n",
315 " '')"
316 ]
317 },
318 {
319 "cell_type": "code",
320 "execution_count": 806,
321 "metadata": {
322 "collapsed": false
323 },
324 "outputs": [
325 {
326 "data": {
327 "text/plain": [
328 "'opgndxcrwomnlnecjz'"
329 ]
330 },
331 "execution_count": 806,
332 "metadata": {},
333 "output_type": "execute_result"
334 }
335 ],
336 "source": [
337 "test_enigma.set_wheels('a', 'a', 'a')\n",
338 "pt = 'thisisatestmessage'\n",
339 "ct = test_enigma.encipher(pt)\n",
340 "ct"
341 ]
342 },
343 {
344 "cell_type": "code",
345 "execution_count": 807,
346 "metadata": {
347 "collapsed": false
348 },
349 "outputs": [
350 {
351 "data": {
352 "text/plain": [
353 "'aas'"
354 ]
355 },
356 "execution_count": 807,
357 "metadata": {},
358 "output_type": "execute_result"
359 }
360 ],
361 "source": [
362 "cat(test_enigma.wheel_positions_l)"
363 ]
364 },
365 {
366 "cell_type": "code",
367 "execution_count": 808,
368 "metadata": {
369 "collapsed": false
370 },
371 "outputs": [
372 {
373 "data": {
374 "text/plain": [
375 "[MenuIem(before='t', after='o', number=1),\n",
376 " MenuIem(before='h', after='p', number=2),\n",
377 " MenuIem(before='i', after='g', number=3),\n",
378 " MenuIem(before='s', after='n', number=4),\n",
379 " MenuIem(before='i', after='d', number=5),\n",
380 " MenuIem(before='s', after='x', number=6),\n",
381 " MenuIem(before='a', after='c', number=7),\n",
382 " MenuIem(before='t', after='r', number=8),\n",
383 " MenuIem(before='e', after='w', number=9),\n",
384 " MenuIem(before='s', after='o', number=10),\n",
385 " MenuIem(before='t', after='m', number=11),\n",
386 " MenuIem(before='m', after='n', number=12),\n",
387 " MenuIem(before='e', after='l', number=13),\n",
388 " MenuIem(before='s', after='n', number=14),\n",
389 " MenuIem(before='s', after='e', number=15),\n",
390 " MenuIem(before='a', after='c', number=16),\n",
391 " MenuIem(before='g', after='j', number=17),\n",
392 " MenuIem(before='e', after='z', number=18)]"
393 ]
394 },
395 "execution_count": 808,
396 "metadata": {},
397 "output_type": "execute_result"
398 }
399 ],
400 "source": [
401 "menu = [MenuItem(p, c, i+1) for i, (p, c) in enumerate(zip(pt, ct))]\n",
402 "menu"
403 ]
404 },
405 {
406 "cell_type": "code",
407 "execution_count": 809,
408 "metadata": {
409 "collapsed": true
410 },
411 "outputs": [],
412 "source": [
413 "def make_menu(plaintext, ciphertext):\n",
414 " return [MenuItem(p, c, i+1) \n",
415 " for i, (p, c) in enumerate(zip(plaintext, ciphertext))]"
416 ]
417 },
418 {
419 "cell_type": "code",
420 "execution_count": 810,
421 "metadata": {
422 "collapsed": false
423 },
424 "outputs": [
425 {
426 "data": {
427 "text/plain": [
428 "[MenuIem(before='t', after='o', number=1),\n",
429 " MenuIem(before='h', after='p', number=2),\n",
430 " MenuIem(before='i', after='g', number=3),\n",
431 " MenuIem(before='s', after='n', number=4),\n",
432 " MenuIem(before='i', after='d', number=5),\n",
433 " MenuIem(before='s', after='x', number=6),\n",
434 " MenuIem(before='a', after='c', number=7),\n",
435 " MenuIem(before='t', after='r', number=8),\n",
436 " MenuIem(before='e', after='w', number=9),\n",
437 " MenuIem(before='s', after='o', number=10),\n",
438 " MenuIem(before='t', after='m', number=11),\n",
439 " MenuIem(before='m', after='n', number=12),\n",
440 " MenuIem(before='e', after='l', number=13),\n",
441 " MenuIem(before='s', after='n', number=14),\n",
442 " MenuIem(before='s', after='e', number=15),\n",
443 " MenuIem(before='a', after='c', number=16),\n",
444 " MenuIem(before='g', after='j', number=17),\n",
445 " MenuIem(before='e', after='z', number=18)]"
446 ]
447 },
448 "execution_count": 810,
449 "metadata": {},
450 "output_type": "execute_result"
451 }
452 ],
453 "source": [
454 "make_menu(pt, ct)"
455 ]
456 },
457 {
458 "cell_type": "code",
459 "execution_count": 811,
460 "metadata": {
461 "collapsed": false
462 },
463 "outputs": [
464 {
465 "data": {
466 "text/plain": [
467 "'s'"
468 ]
469 },
470 "execution_count": 811,
471 "metadata": {},
472 "output_type": "execute_result"
473 }
474 ],
475 "source": [
476 "(collections.Counter(m.before for m in menu) + collections.Counter(m.after for m in menu)).most_common(1)[0][0]"
477 ]
478 },
479 {
480 "cell_type": "code",
481 "execution_count": 812,
482 "metadata": {
483 "collapsed": false
484 },
485 "outputs": [],
486 "source": [
487 "bombe.read_menu(menu)"
488 ]
489 },
490 {
491 "cell_type": "code",
492 "execution_count": 813,
493 "metadata": {
494 "collapsed": false
495 },
496 "outputs": [
497 {
498 "data": {
499 "text/plain": [
500 "18"
501 ]
502 },
503 "execution_count": 813,
504 "metadata": {},
505 "output_type": "execute_result"
506 }
507 ],
508 "source": [
509 "len(bombe.connections)"
510 ]
511 },
512 {
513 "cell_type": "code",
514 "execution_count": 814,
515 "metadata": {
516 "collapsed": false
517 },
518 "outputs": [
519 {
520 "name": "stdout",
521 "output_type": "stream",
522 "text": [
523 "['t', 'o'] aaa\n",
524 "['h', 'p'] aab\n",
525 "['i', 'g'] aac\n",
526 "['s', 'n'] aad\n",
527 "['i', 'd'] aae\n",
528 "['s', 'x'] aaf\n",
529 "['a', 'c'] aag\n",
530 "['t', 'r'] aah\n",
531 "['e', 'w'] aai\n",
532 "['s', 'o'] aaj\n",
533 "['t', 'm'] aak\n",
534 "['m', 'n'] aal\n",
535 "['e', 'l'] aam\n",
536 "['s', 'n'] aan\n",
537 "['s', 'e'] aao\n",
538 "['a', 'c'] aap\n",
539 "['g', 'j'] aaq\n",
540 "['e', 'z'] aar\n"
541 ]
542 }
543 ],
544 "source": [
545 "for c in bombe.connections:\n",
546 " print(c.banks, cat(c.scrambler.wheel_positions_l))"
547 ]
548 },
549 {
550 "cell_type": "code",
551 "execution_count": 815,
552 "metadata": {
553 "collapsed": false
554 },
555 "outputs": [
556 {
557 "data": {
558 "text/plain": [
559 "False"
560 ]
561 },
562 "execution_count": 815,
563 "metadata": {},
564 "output_type": "execute_result"
565 }
566 ],
567 "source": [
568 "bombe.test(Signal('t', 't'))"
569 ]
570 },
571 {
572 "cell_type": "code",
573 "execution_count": 816,
574 "metadata": {
575 "collapsed": false
576 },
577 "outputs": [
578 {
579 "data": {
580 "text/plain": [
581 "{'a': True,\n",
582 " 'b': True,\n",
583 " 'c': True,\n",
584 " 'd': True,\n",
585 " 'e': True,\n",
586 " 'f': True,\n",
587 " 'g': True,\n",
588 " 'h': True,\n",
589 " 'i': True,\n",
590 " 'j': True,\n",
591 " 'k': True,\n",
592 " 'l': True,\n",
593 " 'm': True,\n",
594 " 'n': True,\n",
595 " 'o': True,\n",
596 " 'p': True,\n",
597 " 'q': True,\n",
598 " 'r': True,\n",
599 " 's': True,\n",
600 " 't': True,\n",
601 " 'u': True,\n",
602 " 'v': True,\n",
603 " 'w': True,\n",
604 " 'x': True,\n",
605 " 'y': True,\n",
606 " 'z': True}"
607 ]
608 },
609 "execution_count": 816,
610 "metadata": {},
611 "output_type": "execute_result"
612 }
613 ],
614 "source": [
615 "bombe.banks['t']"
616 ]
617 },
618 {
619 "cell_type": "code",
620 "execution_count": 817,
621 "metadata": {
622 "collapsed": false
623 },
624 "outputs": [
625 {
626 "name": "stdout",
627 "output_type": "stream",
628 "text": [
629 "a : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
630 "b : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n",
631 "c : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
632 "d : ABCDEFGHIJKLMNOPQRSTUVWXyZ\n",
633 "e : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
634 "f : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n",
635 "g : ABCDEFGHIJKLMNOPQRSTuVWXYZ\n",
636 "h : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
637 "i : ABCDEFGHIJKLMNOPQRSTUvWXYZ\n",
638 "j : ABCDEFGHIjKLMNOPQRSTUVWXYZ\n",
639 "k : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n",
640 "l : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
641 "m : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
642 "n : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
643 "o : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
644 "p : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
645 "q : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n",
646 "r : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
647 "s : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
648 "t : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
649 "u : AbCDEfgHIJkLMNOPqRSTuvWXyZ\n",
650 "v : AbCDEfGHiJkLMNOPqRSTuvWXyZ\n",
651 "w : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
652 "x : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n",
653 "y : AbCdEfGHIJkLMNOPqRSTuvWXyZ\n",
654 "z : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
655 ]
656 }
657 ],
658 "source": [
659 "for b in sorted(bombe.banks):\n",
660 " print(b, ': ', end='')\n",
661 " for w in sorted(bombe.banks[b]):\n",
662 " if bombe.banks[b][w]:\n",
663 " print(w.upper(), end='')\n",
664 " else:\n",
665 " print(w, end='')\n",
666 " print('')"
667 ]
668 },
669 {
670 "cell_type": "code",
671 "execution_count": 818,
672 "metadata": {
673 "collapsed": false
674 },
675 "outputs": [
676 {
677 "data": {
678 "text/plain": [
679 "('a', 'a', 'a')"
680 ]
681 },
682 "execution_count": 818,
683 "metadata": {},
684 "output_type": "execute_result"
685 }
686 ],
687 "source": [
688 "bombe.wheel_positions_l"
689 ]
690 },
691 {
692 "cell_type": "code",
693 "execution_count": 819,
694 "metadata": {
695 "collapsed": false
696 },
697 "outputs": [
698 {
699 "name": "stdout",
700 "output_type": "stream",
701 "text": [
702 "['t', 'o'] pqr\n",
703 "['h', 'p'] pqs\n",
704 "['i', 'g'] pqt\n",
705 "['s', 'n'] pqu\n",
706 "['i', 'd'] pqv\n",
707 "['s', 'x'] pqw\n",
708 "['a', 'c'] pqx\n",
709 "['t', 'r'] pqy\n",
710 "['e', 'w'] pqz\n",
711 "['s', 'o'] pqa\n",
712 "['t', 'm'] pqb\n",
713 "['m', 'n'] pqc\n",
714 "['e', 'l'] pqd\n",
715 "['s', 'n'] pqe\n",
716 "['s', 'e'] pqf\n",
717 "['a', 'c'] pqg\n",
718 "['g', 'j'] pqh\n",
719 "['e', 'z'] pqi\n"
720 ]
721 }
722 ],
723 "source": [
724 "bombe.set_positions('p', 'q', 'r')\n",
725 "for c in bombe.connections:\n",
726 " print(c.banks, cat(c.scrambler.wheel_positions_l))"
727 ]
728 },
729 {
730 "cell_type": "code",
731 "execution_count": 820,
732 "metadata": {
733 "collapsed": false
734 },
735 "outputs": [],
736 "source": [
737 "# bombe.run()\n",
738 "# print('x')"
739 ]
740 },
741 {
742 "cell_type": "code",
743 "execution_count": 821,
744 "metadata": {
745 "collapsed": false
746 },
747 "outputs": [
748 {
749 "name": "stdout",
750 "output_type": "stream",
751 "text": [
752 "a : .b.defghijklmnopqrstuvwxyz\n",
753 "b : a.cde.ghij.lmnop.rst..wx.z\n",
754 "c : .b.defghijklmnopqrstuvwxyz\n",
755 "d : abc.e.gh.jklmnopqrstuvwxyz\n",
756 "e : abcd.fghijklmnopqrstuvwxyz\n",
757 "f : a.c.e.g.ij.lmno..rst..wx.z\n",
758 "g : abcdef.h..klmnopqrstuvwxyz\n",
759 "h : abcde.g.ij.lmno.qrst..wxyz\n",
760 "i : abc.ef.h.jklmnopqrstuvwxyz\n",
761 "j : abcdef.hi.klmnopqrstuvwx.z\n",
762 "k : a.cde.g.ij.lmno..rst..wx.z\n",
763 "l : abcdefghijk.mnopqrstuvwxyz\n",
764 "m : abcdefghijkl.nopqrstuvwxyz\n",
765 "n : abcdefghijklm.opqrstuvwxyz\n",
766 "o : abcdefghijklmn.pqrstuvwxyz\n",
767 "p : abcde.g.ij.lmno.qrst..wxyz\n",
768 "q : a.cde.ghij.lmnop.rst..wx.z\n",
769 "r : abcdefghijklmnopq.stuvwxyz\n",
770 "s : abcdefghijklmnopqr.tuvwxyz\n",
771 "t : abcdefghijklmnopqrs.uvwxyz\n",
772 "u : a.cde.g.ij.lmno..rst..wx.z\n",
773 "v : a.cde.g.ij.lmno..rst..wx.z\n",
774 "w : abcdefghijklmnopqrstuv.xyz\n",
775 "x : abcdefghijklmnopqrstuvw.yz\n",
776 "y : a.cde.ghi..lmnop.rst..wx.z\n",
777 "z : abcdefghijklmnopqrstuvwxy.\n"
778 ]
779 }
780 ],
781 "source": [
782 "bombe.set_positions('a', 'a', 'b')\n",
783 "bombe.test(Signal('s', 'a'))\n",
784 "\n",
785 "for b in sorted(bombe.banks):\n",
786 " print(b, ': ', end='')\n",
787 " for w in sorted(bombe.banks[b]):\n",
788 " if bombe.banks[b][w]:\n",
789 " print(w, end='')\n",
790 " else:\n",
791 " print('.', end='')\n",
792 " print('')"
793 ]
794 },
795 {
796 "cell_type": "code",
797 "execution_count": 822,
798 "metadata": {
799 "collapsed": false
800 },
801 "outputs": [
802 {
803 "name": "stdout",
804 "output_type": "stream",
805 "text": [
806 "a : ..........................\n",
807 "b : ..........................\n",
808 "c : ..........................\n",
809 "d : ..........................\n",
810 "e : ....e.....................\n",
811 "f : ..........................\n",
812 "g : ..........................\n",
813 "h : ..........................\n",
814 "i : ..........................\n",
815 "j : ..........................\n",
816 "k : ..........................\n",
817 "l : ...........l..............\n",
818 "m : ............m.............\n",
819 "n : .............n............\n",
820 "o : ..............o...........\n",
821 "p : ..........................\n",
822 "q : ..........................\n",
823 "r : .................r........\n",
824 "s : ..................s.......\n",
825 "t : ...................t......\n",
826 "u : ..........................\n",
827 "v : ..........................\n",
828 "w : ......................w...\n",
829 "x : .......................x..\n",
830 "y : ..........................\n",
831 "z : .........................z\n"
832 ]
833 }
834 ],
835 "source": [
836 "bombe.set_positions('a', 'a', 'b')\n",
837 "bombe.test()\n",
838 "\n",
839 "for b in sorted(bombe.banks):\n",
840 " print(b, ': ', end='')\n",
841 " for w in sorted(bombe.banks[b]):\n",
842 " if bombe.banks[b][w]:\n",
843 " print(w, end='')\n",
844 " else:\n",
845 " print('.', end='')\n",
846 " print('')"
847 ]
848 },
849 {
850 "cell_type": "code",
851 "execution_count": 823,
852 "metadata": {
853 "collapsed": false
854 },
855 "outputs": [
856 {
857 "data": {
858 "text/plain": [
859 "1"
860 ]
861 },
862 "execution_count": 823,
863 "metadata": {},
864 "output_type": "execute_result"
865 }
866 ],
867 "source": [
868 "len([bombe.banks['t'][w] for w in bombe.banks['t'] if bombe.banks['t'][w]])"
869 ]
870 },
871 {
872 "cell_type": "code",
873 "execution_count": 824,
874 "metadata": {
875 "collapsed": false
876 },
877 "outputs": [],
878 "source": [
879 "# %%timeit\n",
880 "# results = bombe.run()\n",
881 "# print(len(results), ('a', 'a', 'b') in results)"
882 ]
883 },
884 {
885 "cell_type": "code",
886 "execution_count": 825,
887 "metadata": {
888 "collapsed": false
889 },
890 "outputs": [],
891 "source": [
892 "# %%timeit\n",
893 "# results = bombe.run(use_diagonal_board=False)\n",
894 "# print(len(results), ('a', 'a', 'b') in results)"
895 ]
896 },
897 {
898 "cell_type": "code",
899 "execution_count": 826,
900 "metadata": {
901 "collapsed": false
902 },
903 "outputs": [
904 {
905 "data": {
906 "text/plain": [
907 "('a', 'a', 'b')"
908 ]
909 },
910 "execution_count": 826,
911 "metadata": {},
912 "output_type": "execute_result"
913 }
914 ],
915 "source": [
916 "bombe.wheel_positions_l"
917 ]
918 },
919 {
920 "cell_type": "code",
921 "execution_count": 827,
922 "metadata": {
923 "collapsed": false
924 },
925 "outputs": [
926 {
927 "data": {
928 "text/plain": [
929 "False"
930 ]
931 },
932 "execution_count": 827,
933 "metadata": {},
934 "output_type": "execute_result"
935 }
936 ],
937 "source": [
938 "bombe.test(Signal('t', 't'), ('p', 'p', 'p'))"
939 ]
940 },
941 {
942 "cell_type": "code",
943 "execution_count": 828,
944 "metadata": {
945 "collapsed": false
946 },
947 "outputs": [
948 {
949 "data": {
950 "text/plain": [
951 "('p', 'p', 'p')"
952 ]
953 },
954 "execution_count": 828,
955 "metadata": {},
956 "output_type": "execute_result"
957 }
958 ],
959 "source": [
960 "bombe.wheel_positions_l"
961 ]
962 },
963 {
964 "cell_type": "code",
965 "execution_count": 829,
966 "metadata": {
967 "collapsed": false
968 },
969 "outputs": [
970 {
971 "name": "stdout",
972 "output_type": "stream",
973 "text": [
974 "a : abcdefghijklmnop.rst.vwxyz\n",
975 "b : a.cde.g.ij.lmno..rst..wx.z\n",
976 "c : abcdefghijklmnop.rst.vwxyz\n",
977 "d : abcdefghijklmnopqrstuvwxyz\n",
978 "e : abcdefghijklmnopqrstuvwxyz\n",
979 "f : a.cde.g.ij.lmno..rst..wx.z\n",
980 "g : abcdefghijklmnopqrstuvwxyz\n",
981 "h : a.cde.ghijklmnop.rst.vwxyz\n",
982 "i : abcdefghijklmnopqrstuvwxyz\n",
983 "j : abcdefghijklmnopqrstuvwxyz\n",
984 "k : a.cde.ghij.lmnop.rst..wx.z\n",
985 "l : abcdefghijklmnopqrstuvwxyz\n",
986 "m : abcdefghijklmnopqrstuvwxyz\n",
987 "n : abcdefghijklmnopqrstuvwxyz\n",
988 "o : abcdefghijklmnopqrstuvwxyz\n",
989 "p : a.cde.ghijklmnop.rst.vwxyz\n",
990 "q : ...de.g.ij.lmno..rst..wx.z\n",
991 "r : abcdefghijklmnopqrstuvwxyz\n",
992 "s : abcdefghijklmnopqrstuvwxyz\n",
993 "t : abcdefghijklmnopqrstuvwxyz\n",
994 "u : ...de.g.ij.lmno..rst..wx.z\n",
995 "v : a.cde.ghij.lmnop.rst..wx.z\n",
996 "w : abcdefghijklmnopqrstuvwxyz\n",
997 "x : abcdefghijklmnopqrstuvwxyz\n",
998 "y : a.cde.ghij.lmnop.rst..wx.z\n",
999 "z : abcdefghijklmnopqrstuvwxyz\n"
1000 ]
1001 }
1002 ],
1003 "source": [
1004 "for b in sorted(bombe.banks):\n",
1005 " print(b, ': ', end='')\n",
1006 " for w in sorted(bombe.banks[b]):\n",
1007 " if bombe.banks[b][w]:\n",
1008 " print(w, end='')\n",
1009 " else:\n",
1010 " print('.', end='')\n",
1011 " print('')"
1012 ]
1013 },
1014 {
1015 "cell_type": "code",
1016 "execution_count": 830,
1017 "metadata": {
1018 "collapsed": false
1019 },
1020 "outputs": [
1021 {
1022 "data": {
1023 "text/plain": [
1024 "17576"
1025 ]
1026 },
1027 "execution_count": 830,
1028 "metadata": {},
1029 "output_type": "execute_result"
1030 }
1031 ],
1032 "source": [
1033 "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1034 "len(list(allwheels))"
1035 ]
1036 },
1037 {
1038 "cell_type": "code",
1039 "execution_count": 831,
1040 "metadata": {
1041 "collapsed": false
1042 },
1043 "outputs": [
1044 {
1045 "data": {
1046 "text/plain": [
1047 "(('a', 'a', 'b'), True)"
1048 ]
1049 },
1050 "execution_count": 831,
1051 "metadata": {},
1052 "output_type": "execute_result"
1053 }
1054 ],
1055 "source": [
1056 "b = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu)\n",
1057 "b(('a', 'a', 'b'))"
1058 ]
1059 },
1060 {
1061 "cell_type": "code",
1062 "execution_count": 832,
1063 "metadata": {
1064 "collapsed": false
1065 },
1066 "outputs": [],
1067 "source": [
1068 "b = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu)(('a', 'a', 'b'))"
1069 ]
1070 },
1071 {
1072 "cell_type": "code",
1073 "execution_count": 833,
1074 "metadata": {
1075 "collapsed": false
1076 },
1077 "outputs": [
1078 {
1079 "data": {
1080 "text/plain": [
1081 "[('a', 'a', 'b')]"
1082 ]
1083 },
1084 "execution_count": 833,
1085 "metadata": {},
1086 "output_type": "execute_result"
1087 }
1088 ],
1089 "source": [
1090 "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1091 "\n",
1092 "with multiprocessing.Pool() as pool:\n",
1093 " res = pool.map(Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu),\n",
1094 " allwheels)\n",
1095 "[r[0] for r in res if r[1]]"
1096 ]
1097 },
1098 {
1099 "cell_type": "code",
1100 "execution_count": 857,
1101 "metadata": {
1102 "collapsed": true
1103 },
1104 "outputs": [],
1105 "source": [
1106 "def run_multi_bombe(wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec, menu,\n",
1107 " start_signal=None, use_diagonal_board=True, \n",
1108 " verify_plugboard=True):\n",
1109 " allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1110 "\n",
1111 " with multiprocessing.Pool() as pool:\n",
1112 " res = pool.map(Bombe(wheel1_spec, wheel2_spec, wheel3_spec, \n",
1113 " reflector_spec, menu=menu, start_signal=start_signal, \n",
1114 " use_diagonal_board=use_diagonal_board, \n",
1115 " verify_plugboard=verify_plugboard),\n",
1116 " allwheels)\n",
1117 " return [r[0] for r in res if r[1]]"
1118 ]
1119 },
1120 {
1121 "cell_type": "code",
1122 "execution_count": 835,
1123 "metadata": {
1124 "collapsed": false
1125 },
1126 "outputs": [
1127 {
1128 "data": {
1129 "text/plain": [
1130 "[('a', 'a', 'b')]"
1131 ]
1132 },
1133 "execution_count": 835,
1134 "metadata": {},
1135 "output_type": "execute_result"
1136 }
1137 ],
1138 "source": [
1139 "[r[0] for r in res if r[1]]"
1140 ]
1141 },
1142 {
1143 "cell_type": "code",
1144 "execution_count": 836,
1145 "metadata": {
1146 "collapsed": false
1147 },
1148 "outputs": [],
1149 "source": [
1150 "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n",
1151 "# Enigma simulation settings are \n",
1152 "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n",
1153 "w_enigma = Enigma(reflector_b_spec, \n",
1154 " wheel_i_spec, wheel_i_pegs,\n",
1155 " wheel_v_spec, wheel_v_pegs,\n",
1156 " wheel_iii_spec, wheel_iii_pegs,\n",
1157 " 6, 20, 24,\n",
1158 " 'ua pf rq so ni ey bg hl tx zj')"
1159 ]
1160 },
1161 {
1162 "cell_type": "code",
1163 "execution_count": 837,
1164 "metadata": {
1165 "collapsed": false
1166 },
1167 "outputs": [
1168 {
1169 "data": {
1170 "text/plain": [
1171 "('e', 'l', 'e')"
1172 ]
1173 },
1174 "execution_count": 837,
1175 "metadata": {},
1176 "output_type": "execute_result"
1177 }
1178 ],
1179 "source": [
1180 "w_enigma.set_wheels('j', 'e', 'b')\n",
1181 "tuple(unpos(p) for p in w_enigma.wheel_positions)"
1182 ]
1183 },
1184 {
1185 "cell_type": "code",
1186 "execution_count": 838,
1187 "metadata": {
1188 "collapsed": false
1189 },
1190 "outputs": [
1191 {
1192 "data": {
1193 "text/plain": [
1194 "'dhnpforeeimgg'"
1195 ]
1196 },
1197 "execution_count": 838,
1198 "metadata": {},
1199 "output_type": "execute_result"
1200 }
1201 ],
1202 "source": [
1203 "w_enigma.set_wheels('j', 'e', 'b')\n",
1204 "pt = 'someplaintext'\n",
1205 "ct = w_enigma.encipher(pt)\n",
1206 "ct"
1207 ]
1208 },
1209 {
1210 "cell_type": "code",
1211 "execution_count": 839,
1212 "metadata": {
1213 "collapsed": false
1214 },
1215 "outputs": [
1216 {
1217 "data": {
1218 "text/plain": [
1219 "('j', 'e', 'o')"
1220 ]
1221 },
1222 "execution_count": 839,
1223 "metadata": {},
1224 "output_type": "execute_result"
1225 }
1226 ],
1227 "source": [
1228 "w_enigma.wheel_positions_l"
1229 ]
1230 },
1231 {
1232 "cell_type": "code",
1233 "execution_count": 840,
1234 "metadata": {
1235 "collapsed": false
1236 },
1237 "outputs": [
1238 {
1239 "data": {
1240 "text/plain": [
1241 "[MenuIem(before='s', after='d', number=1),\n",
1242 " MenuIem(before='o', after='h', number=2),\n",
1243 " MenuIem(before='m', after='n', number=3),\n",
1244 " MenuIem(before='e', after='p', number=4),\n",
1245 " MenuIem(before='p', after='f', number=5),\n",
1246 " MenuIem(before='l', after='o', number=6),\n",
1247 " MenuIem(before='a', after='r', number=7),\n",
1248 " MenuIem(before='i', after='e', number=8),\n",
1249 " MenuIem(before='n', after='e', number=9),\n",
1250 " MenuIem(before='t', after='i', number=10),\n",
1251 " MenuIem(before='e', after='m', number=11),\n",
1252 " MenuIem(before='x', after='g', number=12),\n",
1253 " MenuIem(before='t', after='g', number=13)]"
1254 ]
1255 },
1256 "execution_count": 840,
1257 "metadata": {},
1258 "output_type": "execute_result"
1259 }
1260 ],
1261 "source": [
1262 "w_menu = [MenuItem(p, c, i+1) for i, (p, c) in enumerate(zip(pt, ct))]\n",
1263 "w_menu"
1264 ]
1265 },
1266 {
1267 "cell_type": "code",
1268 "execution_count": 841,
1269 "metadata": {
1270 "collapsed": false,
1271 "scrolled": true
1272 },
1273 "outputs": [
1274 {
1275 "data": {
1276 "text/plain": [
1277 "[('a', 'y', 'm'),\n",
1278 " ('c', 'p', 'v'),\n",
1279 " ('c', 's', 'f'),\n",
1280 " ('c', 'w', 'j'),\n",
1281 " ('d', 'r', 'k'),\n",
1282 " ('e', 'l', 'f'),\n",
1283 " ('e', 's', 'v'),\n",
1284 " ('e', 'y', 'd'),\n",
1285 " ('e', 'y', 'o'),\n",
1286 " ('f', 'z', 'x'),\n",
1287 " ('g', 'b', 'l'),\n",
1288 " ('g', 'c', 'd'),\n",
1289 " ('g', 'c', 'f'),\n",
1290 " ('g', 'j', 'p'),\n",
1291 " ('h', 'c', 'i'),\n",
1292 " ('h', 'm', 'w'),\n",
1293 " ('h', 'o', 'd'),\n",
1294 " ('h', 'p', 'b'),\n",
1295 " ('h', 's', 't'),\n",
1296 " ('i', 'b', 's'),\n",
1297 " ('i', 'v', 'b'),\n",
1298 " ('j', 'y', 'u'),\n",
1299 " ('k', 'b', 'x'),\n",
1300 " ('k', 'f', 't'),\n",
1301 " ('k', 'l', 'e'),\n",
1302 " ('k', 'l', 'm'),\n",
1303 " ('k', 'r', 'z'),\n",
1304 " ('k', 's', 'p'),\n",
1305 " ('l', 'd', 'z'),\n",
1306 " ('l', 'i', 'y'),\n",
1307 " ('l', 'y', 'f'),\n",
1308 " ('m', 'b', 'h'),\n",
1309 " ('m', 'p', 'l'),\n",
1310 " ('n', 'l', 'r'),\n",
1311 " ('o', 'k', 'x'),\n",
1312 " ('p', 'a', 'g'),\n",
1313 " ('p', 'c', 'v'),\n",
1314 " ('p', 'f', 'o'),\n",
1315 " ('p', 'm', 'i'),\n",
1316 " ('p', 'x', 'n'),\n",
1317 " ('p', 'x', 'p'),\n",
1318 " ('q', 'q', 'n'),\n",
1319 " ('q', 'r', 'w'),\n",
1320 " ('q', 'v', 'l'),\n",
1321 " ('q', 'x', 't'),\n",
1322 " ('s', 'a', 'h'),\n",
1323 " ('s', 'h', 'v'),\n",
1324 " ('s', 'l', 'p'),\n",
1325 " ('s', 'l', 's'),\n",
1326 " ('u', 'r', 'h'),\n",
1327 " ('v', 'v', 'v'),\n",
1328 " ('v', 'x', 'a'),\n",
1329 " ('w', 'j', 'z'),\n",
1330 " ('w', 'k', 'u'),\n",
1331 " ('x', 'f', 'p'),\n",
1332 " ('x', 'j', 'n'),\n",
1333 " ('x', 'o', 'q'),\n",
1334 " ('x', 'x', 'x'),\n",
1335 " ('y', 'n', 'c'),\n",
1336 " ('y', 'r', 'f'),\n",
1337 " ('z', 't', 'y'),\n",
1338 " ('z', 'z', 'k')]"
1339 ]
1340 },
1341 "execution_count": 841,
1342 "metadata": {},
1343 "output_type": "execute_result"
1344 }
1345 ],
1346 "source": [
1347 "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1348 "\n",
1349 "with multiprocessing.Pool() as pool:\n",
1350 " res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n",
1351 " menu=w_menu, verify_plugboard=False),\n",
1352 " allwheels)\n",
1353 "[r[0] for r in res if r[1]]"
1354 ]
1355 },
1356 {
1357 "cell_type": "code",
1358 "execution_count": 842,
1359 "metadata": {
1360 "collapsed": false
1361 },
1362 "outputs": [
1363 {
1364 "data": {
1365 "text/plain": [
1366 "62"
1367 ]
1368 },
1369 "execution_count": 842,
1370 "metadata": {},
1371 "output_type": "execute_result"
1372 }
1373 ],
1374 "source": [
1375 "len([r[0] for r in res if r[1]])"
1376 ]
1377 },
1378 {
1379 "cell_type": "code",
1380 "execution_count": 843,
1381 "metadata": {
1382 "collapsed": false,
1383 "scrolled": true
1384 },
1385 "outputs": [
1386 {
1387 "data": {
1388 "text/plain": [
1389 "[('c', 'p', 'v'),\n",
1390 " ('c', 's', 'f'),\n",
1391 " ('e', 'l', 'f'),\n",
1392 " ('g', 'c', 'f'),\n",
1393 " ('j', 'y', 'u'),\n",
1394 " ('o', 'k', 'x'),\n",
1395 " ('p', 'a', 'g'),\n",
1396 " ('q', 'q', 'n'),\n",
1397 " ('q', 'v', 'l'),\n",
1398 " ('q', 'x', 't'),\n",
1399 " ('s', 'l', 'p'),\n",
1400 " ('u', 'r', 'h'),\n",
1401 " ('y', 'n', 'c')]"
1402 ]
1403 },
1404 "execution_count": 843,
1405 "metadata": {},
1406 "output_type": "execute_result"
1407 }
1408 ],
1409 "source": [
1410 "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1411 "\n",
1412 "with multiprocessing.Pool() as pool:\n",
1413 " res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n",
1414 " menu=w_menu, verify_plugboard=True),\n",
1415 " allwheels)\n",
1416 "[r[0] for r in res if r[1]]"
1417 ]
1418 },
1419 {
1420 "cell_type": "code",
1421 "execution_count": 858,
1422 "metadata": {
1423 "collapsed": false
1424 },
1425 "outputs": [
1426 {
1427 "data": {
1428 "text/plain": [
1429 "[('c', 'p', 'v'),\n",
1430 " ('c', 's', 'f'),\n",
1431 " ('e', 'l', 'f'),\n",
1432 " ('g', 'c', 'f'),\n",
1433 " ('j', 'y', 'u'),\n",
1434 " ('o', 'k', 'x'),\n",
1435 " ('p', 'a', 'g'),\n",
1436 " ('q', 'q', 'n'),\n",
1437 " ('q', 'v', 'l'),\n",
1438 " ('q', 'x', 't'),\n",
1439 " ('s', 'l', 'p'),\n",
1440 " ('u', 'r', 'h'),\n",
1441 " ('y', 'n', 'c')]"
1442 ]
1443 },
1444 "execution_count": 858,
1445 "metadata": {},
1446 "output_type": "execute_result"
1447 }
1448 ],
1449 "source": [
1450 "run_multi_bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, w_menu)"
1451 ]
1452 },
1453 {
1454 "cell_type": "code",
1455 "execution_count": 844,
1456 "metadata": {
1457 "collapsed": false
1458 },
1459 "outputs": [],
1460 "source": [
1461 "# allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n",
1462 "\n",
1463 "# with multiprocessing.Pool() as pool:\n",
1464 "# res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n",
1465 "# menu=w_menu, start_signal=Signal('t', 'x')),\n",
1466 "# allwheels)\n",
1467 "# [r[0] for r in res if r[1]]"
1468 ]
1469 },
1470 {
1471 "cell_type": "code",
1472 "execution_count": 845,
1473 "metadata": {
1474 "collapsed": false
1475 },
1476 "outputs": [
1477 {
1478 "data": {
1479 "text/plain": [
1480 "13"
1481 ]
1482 },
1483 "execution_count": 845,
1484 "metadata": {},
1485 "output_type": "execute_result"
1486 }
1487 ],
1488 "source": [
1489 "len([r[0] for r in res if r[1]])"
1490 ]
1491 },
1492 {
1493 "cell_type": "code",
1494 "execution_count": 846,
1495 "metadata": {
1496 "collapsed": false
1497 },
1498 "outputs": [],
1499 "source": [
1500 "w_bombe = Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n",
1501 " menu=w_menu)"
1502 ]
1503 },
1504 {
1505 "cell_type": "code",
1506 "execution_count": 847,
1507 "metadata": {
1508 "collapsed": false
1509 },
1510 "outputs": [
1511 {
1512 "data": {
1513 "text/plain": [
1514 "Signal(bank='e', wire='e')"
1515 ]
1516 },
1517 "execution_count": 847,
1518 "metadata": {},
1519 "output_type": "execute_result"
1520 }
1521 ],
1522 "source": [
1523 "w_bombe.test_start"
1524 ]
1525 },
1526 {
1527 "cell_type": "code",
1528 "execution_count": 848,
1529 "metadata": {
1530 "collapsed": false
1531 },
1532 "outputs": [
1533 {
1534 "data": {
1535 "text/plain": [
1536 "True"
1537 ]
1538 },
1539 "execution_count": 848,
1540 "metadata": {},
1541 "output_type": "execute_result"
1542 }
1543 ],
1544 "source": [
1545 "w_bombe.test(start_positions=('e', 'l', 'f'))"
1546 ]
1547 },
1548 {
1549 "cell_type": "code",
1550 "execution_count": 849,
1551 "metadata": {
1552 "collapsed": false
1553 },
1554 "outputs": [
1555 {
1556 "data": {
1557 "text/plain": [
1558 "True"
1559 ]
1560 },
1561 "execution_count": 849,
1562 "metadata": {},
1563 "output_type": "execute_result"
1564 }
1565 ],
1566 "source": [
1567 "w_bombe.test(Signal('t', 'x'), ('e', 'l', 'f'))"
1568 ]
1569 },
1570 {
1571 "cell_type": "code",
1572 "execution_count": 850,
1573 "metadata": {
1574 "collapsed": false
1575 },
1576 "outputs": [
1577 {
1578 "name": "stdout",
1579 "output_type": "stream",
1580 "text": [
1581 "True\n",
1582 "a : a.cdefghi..l.nopqrst.vwx..\n",
1583 "b : ....efghi...mnop.......x..\n",
1584 "c : a....fg.i..lmn.p.r.t...x..\n",
1585 "d : a...efghij.lmn...rstu..xyz\n",
1586 "e : ab.defghijklmnopqrstuvwxyz\n",
1587 "f : abcde.ghijklmnopqrstuvwxyz\n",
1588 "g : abcdef.hijklmnopqrstuvwxyz\n",
1589 "h : ab.defghi...mnopq.stuvwx..\n",
1590 "i : abcdefgh.jklmnopqrstuvwxyz\n",
1591 "j : ...defg.i...mn.p...t...x..\n",
1592 "k : ....efg.i..lmnop.r.t...x..\n",
1593 "l : a.cdefg.i.k.mnopqr.t..wxyz\n",
1594 "m : .bcdefghijklmnopqrstuvwxyz\n",
1595 "n : abcdefghijklmnopqr.tuvwxyz\n",
1596 "o : ab..efghi.klmnopqr.t...xyz\n",
1597 "p : abc.efghijklmnopqrstuvwxyz\n",
1598 "q : a...efghi..lmnop.r.t...x..\n",
1599 "r : a.cdefg.i.klmnopqrst..w..z\n",
1600 "s : a..defghi...m..p.rstuv.xyz\n",
1601 "t : a.cdefghijklmnopqrstuvwxyz\n",
1602 "u : ...defghi...mn.p..st...x..\n",
1603 "v : a...efghi...mn.p..st...x..\n",
1604 "w : a...efghi..lmn.p.r.t...x..\n",
1605 "x : abcdefghijklmnopq.stuvwxyz\n",
1606 "y : ...defg.i..lmnop..st...x..\n",
1607 "z : ...defg.i..lmnop.rst...x..\n"
1608 ]
1609 }
1610 ],
1611 "source": [
1612 "r = w_bombe.test(start_positions=('c', 'p', 'v'))\n",
1613 "print(r)\n",
1614 "for b in sorted(w_bombe.banks):\n",
1615 " print(b, ': ', end='')\n",
1616 " for w in sorted(w_bombe.banks[b]):\n",
1617 " if w_bombe.banks[b][w]:\n",
1618 " print(w, end='')\n",
1619 " else:\n",
1620 " print('.', end='')\n",
1621 " print('')"
1622 ]
1623 },
1624 {
1625 "cell_type": "code",
1626 "execution_count": 851,
1627 "metadata": {
1628 "collapsed": false
1629 },
1630 "outputs": [
1631 {
1632 "name": "stdout",
1633 "output_type": "stream",
1634 "text": [
1635 "True\n",
1636 "a : abcdefghi..lmnop.rst.v.x.z\n",
1637 "b : a...ef.hi..lmnop.r.t...x..\n",
1638 "c : a..defg.i..lmn.p.rst...x..\n",
1639 "d : a.c.efghi.klmnopqrstu.wxyz\n",
1640 "e : abcdefghijklmnopqrstuvwx.z\n",
1641 "f : abcdefghijklmno.qrstuvwxyz\n",
1642 "g : a.cdefghijklmnopqrstuvwxyz\n",
1643 "h : ab.defghi...mnopqrstuvwxyz\n",
1644 "i : abcdefghijklm.opqrstuvwxyz\n",
1645 "j : ....efg.i..lmnop...t...x..\n",
1646 "k : ...defg.i..lmn.p..st...x..\n",
1647 "l : abcdefg.ijklmnopqrstuv.x..\n",
1648 "m : abcdefghijkl.nopqrstuvwxyz\n",
1649 "n : abcdefgh.jklmnopqrstuvwxyz\n",
1650 "o : ab.defghij.lmnop.r.tuvwxyz\n",
1651 "p : abcde.ghijklmnopqrstuvwxyz\n",
1652 "q : ...defghi..lmn.p..st...x..\n",
1653 "r : abcdefghi..lmnop.rst.v.x.z\n",
1654 "s : a.cdefghi.klmn.pqr.tuvwxyz\n",
1655 "t : abcdefghijklmnopqrstuvw.yz\n",
1656 "u : ...defghi..lmnop..st...x..\n",
1657 "v : a...efghi..lmnop.rst...x..\n",
1658 "w : ...defghi...mnop..st...x..\n",
1659 "x : abcdefghijklmnopqrs.uvwxyz\n",
1660 "y : ...d.fghi...mnop..st...x..\n",
1661 "z : a..defghi...mnop.rst...x..\n"
1662 ]
1663 }
1664 ],
1665 "source": [
1666 "r = w_bombe.test(start_positions=('e', 'l', 'f'))\n",
1667 "print(r)\n",
1668 "for b in sorted(w_bombe.banks):\n",
1669 " print(b, ': ', end='')\n",
1670 " for w in sorted(w_bombe.banks[b]):\n",
1671 " if w_bombe.banks[b][w]:\n",
1672 " print(w, end='')\n",
1673 " else:\n",
1674 " print('.', end='')\n",
1675 " print('')"
1676 ]
1677 },
1678 {
1679 "cell_type": "code",
1680 "execution_count": 852,
1681 "metadata": {
1682 "collapsed": false
1683 },
1684 "outputs": [
1685 {
1686 "data": {
1687 "text/plain": [
1688 "{frozenset({'e', 'y'}),\n",
1689 " frozenset({'t', 'x'}),\n",
1690 " frozenset({'i', 'n'}),\n",
1691 " frozenset({'m'}),\n",
1692 " frozenset({'b', 'g'}),\n",
1693 " frozenset({'f', 'p'})}"
1694 ]
1695 },
1696 "execution_count": 852,
1697 "metadata": {},
1698 "output_type": "execute_result"
1699 }
1700 ],
1701 "source": [
1702 "ps = w_bombe.possible_plugboards()\n",
1703 "ps"
1704 ]
1705 },
1706 {
1707 "cell_type": "code",
1708 "execution_count": 853,
1709 "metadata": {
1710 "collapsed": false
1711 },
1712 "outputs": [
1713 {
1714 "data": {
1715 "text/plain": [
1716 "True"
1717 ]
1718 },
1719 "execution_count": 853,
1720 "metadata": {},
1721 "output_type": "execute_result"
1722 }
1723 ],
1724 "source": [
1725 "all(s0.isdisjoint(s1) for s0 in ps for s1 in ps if s0 != s1)"
1726 ]
1727 },
1728 {
1729 "cell_type": "code",
1730 "execution_count": 854,
1731 "metadata": {
1732 "collapsed": false
1733 },
1734 "outputs": [
1735 {
1736 "data": {
1737 "text/plain": [
1738 "({frozenset({1, 2}), frozenset({2, 3}), frozenset({3, 4})},\n",
1739 " frozenset({1, 2}),\n",
1740 " frozenset({3, 4}),\n",
1741 " frozenset({2, 3}))"
1742 ]
1743 },
1744 "execution_count": 854,
1745 "metadata": {},
1746 "output_type": "execute_result"
1747 }
1748 ],
1749 "source": [
1750 "s = set()\n",
1751 "f1 = frozenset((1, 2))\n",
1752 "f2 = frozenset((3, 4))\n",
1753 "f3 = frozenset((2, 3))\n",
1754 "s = s.union({f1})\n",
1755 "s = s.union({f2})\n",
1756 "s = s.union({f1})\n",
1757 "s = s.union({f3})\n",
1758 "s, f1, f2, f3"
1759 ]
1760 },
1761 {
1762 "cell_type": "code",
1763 "execution_count": 855,
1764 "metadata": {
1765 "collapsed": false
1766 },
1767 "outputs": [
1768 {
1769 "data": {
1770 "text/plain": [
1771 "False"
1772 ]
1773 },
1774 "execution_count": 855,
1775 "metadata": {},
1776 "output_type": "execute_result"
1777 }
1778 ],
1779 "source": [
1780 "all(s0.isdisjoint(s1) for s0 in s for s1 in s if s0 != s1)"
1781 ]
1782 },
1783 {
1784 "cell_type": "code",
1785 "execution_count": 856,
1786 "metadata": {
1787 "collapsed": false
1788 },
1789 "outputs": [
1790 {
1791 "data": {
1792 "text/plain": [
1793 "False"
1794 ]
1795 },
1796 "execution_count": 856,
1797 "metadata": {},
1798 "output_type": "execute_result"
1799 }
1800 ],
1801 "source": [
1802 "{1, 2}.isdisjoint({1, 6})"
1803 ]
1804 },
1805 {
1806 "cell_type": "code",
1807 "execution_count": null,
1808 "metadata": {
1809 "collapsed": true
1810 },
1811 "outputs": [],
1812 "source": []
1813 }
1814 ],
1815 "metadata": {
1816 "kernelspec": {
1817 "display_name": "Python 3",
1818 "language": "python",
1819 "name": "python3"
1820 },
1821 "language_info": {
1822 "codemirror_mode": {
1823 "name": "ipython",
1824 "version": 3
1825 },
1826 "file_extension": ".py",
1827 "mimetype": "text/x-python",
1828 "name": "python",
1829 "nbconvert_exporter": "python",
1830 "pygments_lexer": "ipython3",
1831 "version": "3.5.1+"
1832 }
1833 },
1834 "nbformat": 4,
1835 "nbformat_minor": 0
1836 }