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