Cleaner way of dealing with punctuation in C1b
[cipher-training.git] / enigma.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# Enigma machine\n",
8 "Specification from [Codes and Ciphers](http://www.codesandciphers.org.uk/enigma/rotorspec.htm) page.\n",
9 "\n",
10 "Example Enigma machines from [Louise Dale](http://enigma.louisedade.co.uk/enigma.html) (full simulation) and [EnigmaCo](http://enigmaco.de/enigma/enigma.html) (good animation of the wheels, but no ring settings).\n",
11 "\n",
12 "There's also the nice Enigma simulator for Android by [Franklin Heath](https://franklinheath.co.uk/2012/02/04/our-first-app-published-enigma-simulator/), available on the [Google Play store](https://play.google.com/store/apps/details?id=uk.co.franklinheath.enigmasim&hl=en_GB)."
13 ]
14 },
15 {
16 "cell_type": "code",
17 "execution_count": 1,
18 "metadata": {
19 "collapsed": true
20 },
21 "outputs": [],
22 "source": [
23 "import string\n",
24 "import collections\n",
25 "\n",
26 "cat = ''.join\n",
27 "\n",
28 "def clean(text): return cat(l.lower() for l in text if l in string.ascii_letters)\n",
29 "\n",
30 "def pos(letter): \n",
31 " if letter in string.ascii_lowercase:\n",
32 " return ord(letter) - ord('a')\n",
33 " elif letter in string.ascii_uppercase:\n",
34 " return ord(letter) - ord('A')\n",
35 " else:\n",
36 " return ''\n",
37 " \n",
38 "def unpos(number): return chr(number % 26 + ord('a'))"
39 ]
40 },
41 {
42 "cell_type": "code",
43 "execution_count": 2,
44 "metadata": {
45 "collapsed": true
46 },
47 "outputs": [],
48 "source": [
49 "wheel_i_spec = 'ekmflgdqvzntowyhxuspaibrcj'\n",
50 "wheel_ii_spec = 'ajdksiruxblhwtmcqgznpyfvoe'\n",
51 "wheel_iii_spec = 'bdfhjlcprtxvznyeiwgakmusqo'\n",
52 "wheel_iv_spec = 'esovpzjayquirhxlnftgkdcmwb'\n",
53 "wheel_v_spec = 'vzbrgityupsdnhlxawmjqofeck'\n",
54 "wheel_vi_spec = 'jpgvoumfyqbenhzrdkasxlictw'\n",
55 "wheel_vii_spec = 'nzjhgrcxmyswboufaivlpekqdt'\n",
56 "wheel_viii_spec = 'fkqhtlxocbjspdzramewniuygv'\n",
57 "beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos'\n",
58 "gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd'\n",
59 "\n",
60 "wheel_i_pegs = ['q']\n",
61 "wheel_ii_pegs = ['e']\n",
62 "wheel_iii_pegs = ['v']\n",
63 "wheel_iv_pegs = ['j']\n",
64 "wheel_v_pegs = ['z']\n",
65 "wheel_vi_pegs = ['z', 'm']\n",
66 "wheel_vii_pegs = ['z', 'm']\n",
67 "wheel_viii_pegs = ['z', 'm']\n",
68 "\n",
69 "reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw'\n",
70 "reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su'"
71 ]
72 },
73 {
74 "cell_type": "code",
75 "execution_count": 3,
76 "metadata": {
77 "collapsed": false
78 },
79 "outputs": [],
80 "source": [
81 "class LetterTransformer(object):\n",
82 " def __init__(self, specification, raw_transform=False):\n",
83 " if raw_transform:\n",
84 " transform = specification\n",
85 " else:\n",
86 " transform = self.parse_specification(specification)\n",
87 " self.validate_transform(transform)\n",
88 " self.make_transform_map(transform)\n",
89 " \n",
90 " def parse_specification(self, specification):\n",
91 " return list(zip(string.ascii_lowercase, clean(specification)))\n",
92 " # return specification\n",
93 " \n",
94 " def validate_transform(self, transform):\n",
95 " \"\"\"A set of pairs, of from-to\"\"\"\n",
96 " if len(transform) != 26:\n",
97 " raise ValueError(\"Transform specification has {} pairs, requires 26\".\n",
98 " format(len(transform)))\n",
99 " for p in transform:\n",
100 " if len(p) != 2:\n",
101 " raise ValueError(\"Not all mappings in transform \"\n",
102 " \"have two elements\")\n",
103 " if len(set([p[0] for p in transform])) != 26:\n",
104 " raise ValueError(\"Transform specification must list 26 origin letters\") \n",
105 " if len(set([p[1] for p in transform])) != 26:\n",
106 " raise ValueError(\"Transform specification must list 26 destination letters\") \n",
107 "\n",
108 " def make_empty_transform(self):\n",
109 " self.forward_map = [0] * 26\n",
110 " self.backward_map = [0] * 26\n",
111 " \n",
112 " def make_transform_map(self, transform):\n",
113 " self.make_empty_transform()\n",
114 " for p in transform:\n",
115 " self.forward_map[pos(p[0])] = pos(p[1])\n",
116 " self.backward_map[pos(p[1])] = pos(p[0])\n",
117 " return self.forward_map, self.backward_map\n",
118 " \n",
119 " def forward(self, letter):\n",
120 " if letter in string.ascii_lowercase:\n",
121 " return unpos(self.forward_map[pos(letter)])\n",
122 " else:\n",
123 " return ''\n",
124 " \n",
125 " def backward(self, letter):\n",
126 " if letter in string.ascii_lowercase:\n",
127 " return unpos(self.backward_map[pos(letter)])\n",
128 " else:\n",
129 " return ''"
130 ]
131 },
132 {
133 "cell_type": "code",
134 "execution_count": 4,
135 "metadata": {
136 "collapsed": false
137 },
138 "outputs": [
139 {
140 "data": {
141 "text/plain": [
142 "[('z', 'a'),\n",
143 " ('a', 'b'),\n",
144 " ('b', 'c'),\n",
145 " ('c', 'd'),\n",
146 " ('d', 'e'),\n",
147 " ('e', 'f'),\n",
148 " ('f', 'g'),\n",
149 " ('g', 'h'),\n",
150 " ('h', 'i'),\n",
151 " ('i', 'j'),\n",
152 " ('j', 'k'),\n",
153 " ('k', 'l'),\n",
154 " ('l', 'm'),\n",
155 " ('m', 'n'),\n",
156 " ('n', 'o'),\n",
157 " ('o', 'p'),\n",
158 " ('p', 'q'),\n",
159 " ('q', 'r'),\n",
160 " ('r', 's'),\n",
161 " ('s', 't'),\n",
162 " ('t', 'u'),\n",
163 " ('u', 'v'),\n",
164 " ('v', 'w'),\n",
165 " ('w', 'x'),\n",
166 " ('x', 'y'),\n",
167 " ('y', 'z')]"
168 ]
169 },
170 "execution_count": 4,
171 "metadata": {},
172 "output_type": "execute_result"
173 }
174 ],
175 "source": [
176 "tmap = [('z', 'a')] + [(l, string.ascii_lowercase[i+1]) for i, l in enumerate(string.ascii_lowercase[:-1])]\n",
177 "tmap"
178 ]
179 },
180 {
181 "cell_type": "code",
182 "execution_count": 5,
183 "metadata": {
184 "collapsed": false
185 },
186 "outputs": [
187 {
188 "data": {
189 "text/plain": [
190 "'zyxwcabdefghijklmnopqrstuv'"
191 ]
192 },
193 "execution_count": 5,
194 "metadata": {},
195 "output_type": "execute_result"
196 }
197 ],
198 "source": [
199 "cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase))"
200 ]
201 },
202 {
203 "cell_type": "code",
204 "execution_count": 6,
205 "metadata": {
206 "collapsed": false,
207 "scrolled": true
208 },
209 "outputs": [],
210 "source": [
211 "tmap2 = list(zip(string.ascii_lowercase, cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase))))"
212 ]
213 },
214 {
215 "cell_type": "code",
216 "execution_count": 7,
217 "metadata": {
218 "collapsed": false,
219 "scrolled": true
220 },
221 "outputs": [
222 {
223 "data": {
224 "text/plain": [
225 "([1,\n",
226 " 2,\n",
227 " 3,\n",
228 " 4,\n",
229 " 5,\n",
230 " 6,\n",
231 " 7,\n",
232 " 8,\n",
233 " 9,\n",
234 " 10,\n",
235 " 11,\n",
236 " 12,\n",
237 " 13,\n",
238 " 14,\n",
239 " 15,\n",
240 " 16,\n",
241 " 17,\n",
242 " 18,\n",
243 " 19,\n",
244 " 20,\n",
245 " 21,\n",
246 " 22,\n",
247 " 23,\n",
248 " 24,\n",
249 " 25,\n",
250 " 0],\n",
251 " [25,\n",
252 " 0,\n",
253 " 1,\n",
254 " 2,\n",
255 " 3,\n",
256 " 4,\n",
257 " 5,\n",
258 " 6,\n",
259 " 7,\n",
260 " 8,\n",
261 " 9,\n",
262 " 10,\n",
263 " 11,\n",
264 " 12,\n",
265 " 13,\n",
266 " 14,\n",
267 " 15,\n",
268 " 16,\n",
269 " 17,\n",
270 " 18,\n",
271 " 19,\n",
272 " 20,\n",
273 " 21,\n",
274 " 22,\n",
275 " 23,\n",
276 " 24])"
277 ]
278 },
279 "execution_count": 7,
280 "metadata": {},
281 "output_type": "execute_result"
282 }
283 ],
284 "source": [
285 "lt = LetterTransformer(tmap, raw_transform = True)\n",
286 "assert(lt.forward_map == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0])\n",
287 "assert(lt.backward_map == [25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])\n",
288 "lt.forward_map, lt.backward_map"
289 ]
290 },
291 {
292 "cell_type": "code",
293 "execution_count": 8,
294 "metadata": {
295 "collapsed": false,
296 "scrolled": true
297 },
298 "outputs": [
299 {
300 "data": {
301 "text/plain": [
302 "([25,\n",
303 " 24,\n",
304 " 23,\n",
305 " 22,\n",
306 " 2,\n",
307 " 0,\n",
308 " 1,\n",
309 " 3,\n",
310 " 4,\n",
311 " 5,\n",
312 " 6,\n",
313 " 7,\n",
314 " 8,\n",
315 " 9,\n",
316 " 10,\n",
317 " 11,\n",
318 " 12,\n",
319 " 13,\n",
320 " 14,\n",
321 " 15,\n",
322 " 16,\n",
323 " 17,\n",
324 " 18,\n",
325 " 19,\n",
326 " 20,\n",
327 " 21],\n",
328 " [5,\n",
329 " 6,\n",
330 " 4,\n",
331 " 7,\n",
332 " 8,\n",
333 " 9,\n",
334 " 10,\n",
335 " 11,\n",
336 " 12,\n",
337 " 13,\n",
338 " 14,\n",
339 " 15,\n",
340 " 16,\n",
341 " 17,\n",
342 " 18,\n",
343 " 19,\n",
344 " 20,\n",
345 " 21,\n",
346 " 22,\n",
347 " 23,\n",
348 " 24,\n",
349 " 25,\n",
350 " 3,\n",
351 " 2,\n",
352 " 1,\n",
353 " 0])"
354 ]
355 },
356 "execution_count": 8,
357 "metadata": {},
358 "output_type": "execute_result"
359 }
360 ],
361 "source": [
362 "lt = LetterTransformer(cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase)))\n",
363 "assert(lt.forward_map == [25, 24, 23, 22, 2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])\n",
364 "assert(lt.backward_map == [5, 6, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 3, 2, 1, 0])\n",
365 "assert(cat(lt.forward(l) for l in string.ascii_lowercase) == 'zyxwcabdefghijklmnopqrstuv')\n",
366 "assert(cat(lt.backward(l) for l in string.ascii_lowercase) == 'fgehijklmnopqrstuvwxyzdcba')\n",
367 "lt.forward_map, lt.backward_map"
368 ]
369 },
370 {
371 "cell_type": "code",
372 "execution_count": 9,
373 "metadata": {
374 "collapsed": false
375 },
376 "outputs": [
377 {
378 "data": {
379 "text/plain": [
380 "'zyxwcabdefghijklmnopqrstuv'"
381 ]
382 },
383 "execution_count": 9,
384 "metadata": {},
385 "output_type": "execute_result"
386 }
387 ],
388 "source": [
389 "cat(lt.forward(l) for l in string.ascii_lowercase)"
390 ]
391 },
392 {
393 "cell_type": "code",
394 "execution_count": 10,
395 "metadata": {
396 "collapsed": false
397 },
398 "outputs": [
399 {
400 "data": {
401 "text/plain": [
402 "'fgehijklmnopqrstuvwxyzdcba'"
403 ]
404 },
405 "execution_count": 10,
406 "metadata": {},
407 "output_type": "execute_result"
408 }
409 ],
410 "source": [
411 "cat(lt.backward(l) for l in string.ascii_lowercase)"
412 ]
413 },
414 {
415 "cell_type": "code",
416 "execution_count": 11,
417 "metadata": {
418 "collapsed": true
419 },
420 "outputs": [],
421 "source": [
422 "class Plugboard(LetterTransformer):\n",
423 " def parse_specification(self, specification):\n",
424 " return [tuple(clean(p)) for p in specification.split()]\n",
425 " \n",
426 " def validate_transform(self, transform):\n",
427 " \"\"\"A set of pairs, of from-to\"\"\"\n",
428 " for p in transform:\n",
429 " if len(p) != 2:\n",
430 " raise ValueError(\"Not all mappings in transform\"\n",
431 " \"have two elements\")\n",
432 " \n",
433 " def make_empty_transform(self):\n",
434 " self.forward_map = list(range(26))\n",
435 " self.backward_map = list(range(26))\n",
436 " \n",
437 " def make_transform_map(self, transform):\n",
438 " expanded_transform = transform + [tuple(reversed(p)) for p in transform]\n",
439 " return super(Plugboard, self).make_transform_map(expanded_transform)"
440 ]
441 },
442 {
443 "cell_type": "code",
444 "execution_count": 12,
445 "metadata": {
446 "collapsed": false
447 },
448 "outputs": [],
449 "source": [
450 "pb = Plugboard([('a', 'z'), ('b', 'y')], raw_transform=True)"
451 ]
452 },
453 {
454 "cell_type": "code",
455 "execution_count": 13,
456 "metadata": {
457 "collapsed": false
458 },
459 "outputs": [
460 {
461 "data": {
462 "text/plain": [
463 "'zycdefghijklmnopqrstuvwxba'"
464 ]
465 },
466 "execution_count": 13,
467 "metadata": {},
468 "output_type": "execute_result"
469 }
470 ],
471 "source": [
472 "cat(pb.forward(l) for l in string.ascii_lowercase)"
473 ]
474 },
475 {
476 "cell_type": "code",
477 "execution_count": 14,
478 "metadata": {
479 "collapsed": false
480 },
481 "outputs": [
482 {
483 "data": {
484 "text/plain": [
485 "'zycdefghijklmnopqrstuvwxba'"
486 ]
487 },
488 "execution_count": 14,
489 "metadata": {},
490 "output_type": "execute_result"
491 }
492 ],
493 "source": [
494 "cat(pb.backward(l) for l in string.ascii_lowercase)"
495 ]
496 },
497 {
498 "cell_type": "code",
499 "execution_count": 15,
500 "metadata": {
501 "collapsed": false
502 },
503 "outputs": [],
504 "source": [
505 "pb = Plugboard('az by')"
506 ]
507 },
508 {
509 "cell_type": "code",
510 "execution_count": 16,
511 "metadata": {
512 "collapsed": false
513 },
514 "outputs": [
515 {
516 "data": {
517 "text/plain": [
518 "('zycdefghijklmnopqrstuvwxba', 'zycdefghijklmnopqrstuvwxba')"
519 ]
520 },
521 "execution_count": 16,
522 "metadata": {},
523 "output_type": "execute_result"
524 }
525 ],
526 "source": [
527 "cat(pb.forward(l) for l in string.ascii_lowercase), cat(pb.backward(l) for l in string.ascii_lowercase)"
528 ]
529 },
530 {
531 "cell_type": "code",
532 "execution_count": 17,
533 "metadata": {
534 "collapsed": false
535 },
536 "outputs": [
537 {
538 "data": {
539 "text/plain": [
540 "('ugcdypblnzkhmisfrqoxavwtej', 'ugcdypblnzkhmisfrqoxavwtej')"
541 ]
542 },
543 "execution_count": 17,
544 "metadata": {},
545 "output_type": "execute_result"
546 }
547 ],
548 "source": [
549 "pb = Plugboard('ua pf rq so ni ey bg hl tx zj'.upper())\n",
550 "assert(pb.forward_map == pb.backward_map)\n",
551 "assert(pb.forward_map == [20, 6, 2, 3, 24, 15, 1, 11, 13, 25, 10, 7, 12, 8, 18, 5, 17, 16, 14, 23, 0, 21, 22, 19, 4, 9])\n",
552 "assert(cat(pb.forward(l) for l in string.ascii_lowercase) == 'ugcdypblnzkhmisfrqoxavwtej')\n",
553 "assert(cat(pb.backward(l) for l in string.ascii_lowercase) == 'ugcdypblnzkhmisfrqoxavwtej')\n",
554 "cat(pb.forward(l) for l in string.ascii_lowercase), cat(pb.backward(l) for l in string.ascii_lowercase)"
555 ]
556 },
557 {
558 "cell_type": "code",
559 "execution_count": 18,
560 "metadata": {
561 "collapsed": true
562 },
563 "outputs": [],
564 "source": [
565 "class Reflector(Plugboard):\n",
566 " def validate_transform(self, transform):\n",
567 " if len(transform) != 13:\n",
568 " raise ValueError(\"Reflector specification has {} pairs, requires 13\".\n",
569 " format(len(transform)))\n",
570 " if len(set([p[0] for p in transform] + \n",
571 " [p[1] for p in transform])) != 26:\n",
572 " raise ValueError(\"Reflector specification does not contain 26 letters\")\n",
573 " try:\n",
574 " super(Reflector, self).validate_transform(transform)\n",
575 " except ValueError as v:\n",
576 " raise ValueError(\"Not all mappings in reflector have two elements\")"
577 ]
578 },
579 {
580 "cell_type": "code",
581 "execution_count": 19,
582 "metadata": {
583 "collapsed": false
584 },
585 "outputs": [
586 {
587 "data": {
588 "text/plain": [
589 "[('a', 'y'),\n",
590 " ('b', 'r'),\n",
591 " ('c', 'u'),\n",
592 " ('d', 'h'),\n",
593 " ('e', 'q'),\n",
594 " ('f', 's'),\n",
595 " ('g', 'l'),\n",
596 " ('i', 'p'),\n",
597 " ('j', 'x'),\n",
598 " ('k', 'n'),\n",
599 " ('m', 'o'),\n",
600 " ('t', 'z'),\n",
601 " ('v', 'w')]"
602 ]
603 },
604 "execution_count": 19,
605 "metadata": {},
606 "output_type": "execute_result"
607 }
608 ],
609 "source": [
610 "# reflector_b_text = '(AY) (BR) (CU) (DH) (EQ) (FS) (GL) (IP) (JX) (KN) (MO) (TZ) (VW)'\n",
611 "reflector_b_l = [tuple(clean(p)) for p in reflector_b_spec.split()]\n",
612 "reflector_b_l"
613 ]
614 },
615 {
616 "cell_type": "code",
617 "execution_count": 20,
618 "metadata": {
619 "collapsed": false
620 },
621 "outputs": [],
622 "source": [
623 "reflector_b = Reflector(reflector_b_spec)\n",
624 "assert(reflector_b.forward_map == reflector_b.backward_map)\n",
625 "assert(reflector_b.forward_map == [24, 17, 20, 7, 16, 18, 11, 3, 15, 23, 13, 6, 14, 10, 12, 8, 4, 1, 5, 25, 2, 22, 21, 9, 0, 19])\n",
626 "assert(cat(reflector_b.forward(l) for l in string.ascii_lowercase) == 'yruhqsldpxngokmiebfzcwvjat')\n",
627 "assert(cat(reflector_b.backward(l) for l in string.ascii_lowercase) == 'yruhqsldpxngokmiebfzcwvjat')"
628 ]
629 },
630 {
631 "cell_type": "code",
632 "execution_count": 21,
633 "metadata": {
634 "collapsed": false
635 },
636 "outputs": [
637 {
638 "data": {
639 "text/plain": [
640 "'yruhqsldpxngokmiebfzcwvjat'"
641 ]
642 },
643 "execution_count": 21,
644 "metadata": {},
645 "output_type": "execute_result"
646 }
647 ],
648 "source": [
649 "cat(reflector_b.forward(l) for l in string.ascii_lowercase)"
650 ]
651 },
652 {
653 "cell_type": "code",
654 "execution_count": 22,
655 "metadata": {
656 "collapsed": false
657 },
658 "outputs": [],
659 "source": [
660 "reflector_c = Reflector(reflector_c_spec)"
661 ]
662 },
663 {
664 "cell_type": "code",
665 "execution_count": 23,
666 "metadata": {
667 "collapsed": false
668 },
669 "outputs": [
670 {
671 "data": {
672 "text/plain": [
673 "'fvpjiaoyedrzxwgctkuqsbnmhl'"
674 ]
675 },
676 "execution_count": 23,
677 "metadata": {},
678 "output_type": "execute_result"
679 }
680 ],
681 "source": [
682 "cat(reflector_c.forward(l) for l in string.ascii_lowercase)"
683 ]
684 },
685 {
686 "cell_type": "code",
687 "execution_count": 24,
688 "metadata": {
689 "collapsed": true
690 },
691 "outputs": [],
692 "source": [
693 "class SimpleWheel(LetterTransformer):\n",
694 " def __init__(self, transform, position='a', raw_transform=False):\n",
695 " super(SimpleWheel, self).__init__(transform, raw_transform)\n",
696 " self.set_position(position)\n",
697 " \n",
698 " def __getattribute__(self,name):\n",
699 " if name=='position_l':\n",
700 " return unpos(self.position)\n",
701 " else:\n",
702 " return object.__getattribute__(self, name)\n",
703 " \n",
704 " def set_position(self, position):\n",
705 " self.position = ord(position) - ord('a')\n",
706 " \n",
707 " def forward(self, letter):\n",
708 " if letter in string.ascii_lowercase:\n",
709 " return unpos((self.forward_map[(pos(letter) + self.position) % 26] - self.position))\n",
710 " else:\n",
711 " return ''\n",
712 " \n",
713 " def backward(self, letter):\n",
714 " if letter in string.ascii_lowercase:\n",
715 " return unpos((self.backward_map[(pos(letter) + self.position) % 26] - self.position))\n",
716 " else:\n",
717 " return ''\n",
718 " \n",
719 " def advance(self):\n",
720 " self.position = (self.position + 1) % 26\n",
721 " return self.position"
722 ]
723 },
724 {
725 "cell_type": "code",
726 "execution_count": 25,
727 "metadata": {
728 "collapsed": false,
729 "scrolled": true
730 },
731 "outputs": [
732 {
733 "data": {
734 "text/plain": [
735 "[('a', 'e'),\n",
736 " ('b', 'k'),\n",
737 " ('c', 'm'),\n",
738 " ('d', 'f'),\n",
739 " ('e', 'l'),\n",
740 " ('f', 'g'),\n",
741 " ('g', 'd'),\n",
742 " ('h', 'q'),\n",
743 " ('i', 'v'),\n",
744 " ('j', 'z'),\n",
745 " ('k', 'n'),\n",
746 " ('l', 't'),\n",
747 " ('m', 'o'),\n",
748 " ('n', 'w'),\n",
749 " ('o', 'y'),\n",
750 " ('p', 'h'),\n",
751 " ('q', 'x'),\n",
752 " ('r', 'u'),\n",
753 " ('s', 's'),\n",
754 " ('t', 'p'),\n",
755 " ('u', 'a'),\n",
756 " ('v', 'i'),\n",
757 " ('w', 'b'),\n",
758 " ('x', 'r'),\n",
759 " ('y', 'c'),\n",
760 " ('z', 'j')]"
761 ]
762 },
763 "execution_count": 25,
764 "metadata": {},
765 "output_type": "execute_result"
766 }
767 ],
768 "source": [
769 "rotor_1_transform = list(zip(string.ascii_lowercase, 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower()))\n",
770 "rotor_1_transform"
771 ]
772 },
773 {
774 "cell_type": "code",
775 "execution_count": 26,
776 "metadata": {
777 "collapsed": false
778 },
779 "outputs": [],
780 "source": [
781 "rotor_1_transform = list(zip(string.ascii_lowercase, 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower()))\n",
782 "wheel_1 = SimpleWheel(rotor_1_transform, raw_transform=True)\n",
783 "assert(cat(wheel_1.forward(l) for l in string.ascii_lowercase) == 'ekmflgdqvzntowyhxuspaibrcj')\n",
784 "assert(cat(wheel_1.backward(l) for l in string.ascii_lowercase) == 'uwygadfpvzbeckmthxslrinqoj')"
785 ]
786 },
787 {
788 "cell_type": "code",
789 "execution_count": 27,
790 "metadata": {
791 "collapsed": false
792 },
793 "outputs": [
794 {
795 "data": {
796 "text/plain": [
797 "('ekmflgdqvzntowyhxuspaibrcj', 'uwygadfpvzbeckmthxslrinqoj')"
798 ]
799 },
800 "execution_count": 27,
801 "metadata": {},
802 "output_type": "execute_result"
803 }
804 ],
805 "source": [
806 "cat(wheel_1.forward(l) for l in string.ascii_lowercase), cat(wheel_1.backward(l) for l in string.ascii_lowercase)"
807 ]
808 },
809 {
810 "cell_type": "code",
811 "execution_count": 28,
812 "metadata": {
813 "collapsed": false
814 },
815 "outputs": [
816 {
817 "data": {
818 "text/plain": [
819 "'a'"
820 ]
821 },
822 "execution_count": 28,
823 "metadata": {},
824 "output_type": "execute_result"
825 }
826 ],
827 "source": [
828 "wheel_1.position_l"
829 ]
830 },
831 {
832 "cell_type": "code",
833 "execution_count": 29,
834 "metadata": {
835 "collapsed": false
836 },
837 "outputs": [],
838 "source": [
839 "wheel_2 = SimpleWheel(wheel_ii_spec)\n",
840 "assert(cat(wheel_2.forward(l) for l in string.ascii_lowercase) == 'ajdksiruxblhwtmcqgznpyfvoe')\n",
841 "assert(cat(wheel_2.backward(l) for l in string.ascii_lowercase) == 'ajpczwrlfbdkotyuqgenhxmivs')"
842 ]
843 },
844 {
845 "cell_type": "code",
846 "execution_count": 30,
847 "metadata": {
848 "collapsed": false
849 },
850 "outputs": [
851 {
852 "data": {
853 "text/plain": [
854 "('ajdksiruxblhwtmcqgznpyfvoe', 'ajpczwrlfbdkotyuqgenhxmivs')"
855 ]
856 },
857 "execution_count": 30,
858 "metadata": {},
859 "output_type": "execute_result"
860 }
861 ],
862 "source": [
863 "cat(wheel_2.forward(l) for l in string.ascii_lowercase), cat(wheel_2.backward(l) for l in string.ascii_lowercase)"
864 ]
865 },
866 {
867 "cell_type": "code",
868 "execution_count": 31,
869 "metadata": {
870 "collapsed": false
871 },
872 "outputs": [
873 {
874 "data": {
875 "text/plain": [
876 "('bdfhjlcprtxvznyeiwgakmusqo', 'tagbpcsdqeufvnzhyixjwlrkom')"
877 ]
878 },
879 "execution_count": 31,
880 "metadata": {},
881 "output_type": "execute_result"
882 }
883 ],
884 "source": [
885 "wheel_3 = SimpleWheel(wheel_iii_spec)\n",
886 "wheel_3.set_position('a')\n",
887 "wheel_3.advance()\n",
888 "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'cegikboqswuymxdhvfzjltrpna')\n",
889 "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'zfaobrcpdteumygxhwivkqjnls')\n",
890 "assert(wheel_3.position == 1)\n",
891 "assert(wheel_3.position_l == 'b')\n",
892 "\n",
893 "for _ in range(24): wheel_3.advance()\n",
894 "assert(wheel_3.position == 25)\n",
895 "assert(wheel_3.position_l == 'z')\n",
896 "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'pcegikmdqsuywaozfjxhblnvtr')\n",
897 "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'nubhcqdterfvgwoaizjykxmslp')\n",
898 "\n",
899 "wheel_3.advance()\n",
900 "assert(wheel_3.position == 0)\n",
901 "assert(wheel_3.position_l == 'a')\n",
902 "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'bdfhjlcprtxvznyeiwgakmusqo')\n",
903 "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'tagbpcsdqeufvnzhyixjwlrkom')\n",
904 "\n",
905 "cat(wheel_3.forward(l) for l in string.ascii_lowercase), cat(wheel_3.backward(l) for l in string.ascii_lowercase)"
906 ]
907 },
908 {
909 "cell_type": "code",
910 "execution_count": 32,
911 "metadata": {
912 "collapsed": false
913 },
914 "outputs": [],
915 "source": [
916 "class Wheel(SimpleWheel):\n",
917 " def __init__(self, transform, ring_peg_letters, ring_setting=1, position='a', raw_transform=False):\n",
918 " self.ring_peg_letters = ring_peg_letters\n",
919 " self.ring_setting = ring_setting\n",
920 " super(Wheel, self).__init__(transform, position=position, raw_transform=raw_transform)\n",
921 " self.set_position(position)\n",
922 " \n",
923 " def __getattribute__(self,name):\n",
924 " if name=='position_l':\n",
925 " return unpos(self.position + self.ring_setting - 1)\n",
926 " else:\n",
927 " return object.__getattribute__(self, name)\n",
928 "\n",
929 " def set_position(self, position):\n",
930 " self.position = (pos(position) - self.ring_setting + 1) % 26\n",
931 " # self.position_l = position\n",
932 " self.peg_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_peg_letters]\n",
933 " \n",
934 " def advance(self):\n",
935 " super(Wheel, self).advance()\n",
936 " self.peg_positions = [(p - 1) % 26 for p in self.peg_positions]\n",
937 " # self.position_l = unpos(self.position + self.ring_setting - 1)\n",
938 " return self.position"
939 ]
940 },
941 {
942 "cell_type": "code",
943 "execution_count": 33,
944 "metadata": {
945 "collapsed": false
946 },
947 "outputs": [],
948 "source": [
949 "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)"
950 ]
951 },
952 {
953 "cell_type": "code",
954 "execution_count": 34,
955 "metadata": {
956 "collapsed": false
957 },
958 "outputs": [
959 {
960 "data": {
961 "text/plain": [
962 "(1, [20])"
963 ]
964 },
965 "execution_count": 34,
966 "metadata": {},
967 "output_type": "execute_result"
968 }
969 ],
970 "source": [
971 "wheel_3.position, wheel_3.peg_positions"
972 ]
973 },
974 {
975 "cell_type": "code",
976 "execution_count": 35,
977 "metadata": {
978 "collapsed": false
979 },
980 "outputs": [
981 {
982 "data": {
983 "text/plain": [
984 "(25, [24, 11])"
985 ]
986 },
987 "execution_count": 35,
988 "metadata": {},
989 "output_type": "execute_result"
990 }
991 ],
992 "source": [
993 "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n",
994 "wheel_6.position, wheel_6.peg_positions"
995 ]
996 },
997 {
998 "cell_type": "code",
999 "execution_count": 36,
1000 "metadata": {
1001 "collapsed": false,
1002 "scrolled": true
1003 },
1004 "outputs": [
1005 {
1006 "name": "stdout",
1007 "output_type": "stream",
1008 "text": [
1009 "0 [23, 10]\n",
1010 "1 [22, 9]\n",
1011 "2 [21, 8]\n",
1012 "3 [20, 7]\n",
1013 "4 [19, 6]\n",
1014 "5 [18, 5]\n",
1015 "6 [17, 4]\n",
1016 "7 [16, 3]\n",
1017 "8 [15, 2]\n",
1018 "9 [14, 1]\n",
1019 "10 [13, 0]\n",
1020 "11 [12, 25]\n",
1021 "12 [11, 24]\n",
1022 "13 [10, 23]\n",
1023 "14 [9, 22]\n",
1024 "15 [8, 21]\n",
1025 "16 [7, 20]\n",
1026 "17 [6, 19]\n",
1027 "18 [5, 18]\n",
1028 "19 [4, 17]\n",
1029 "20 [3, 16]\n",
1030 "21 [2, 15]\n",
1031 "22 [1, 14]\n",
1032 "23 [0, 13]\n",
1033 "24 [25, 12]\n",
1034 "25 [24, 11]\n",
1035 "0 [23, 10]\n"
1036 ]
1037 }
1038 ],
1039 "source": [
1040 "for _ in range(27):\n",
1041 " wheel_6.advance()\n",
1042 " print(wheel_6.position, wheel_6.peg_positions)"
1043 ]
1044 },
1045 {
1046 "cell_type": "code",
1047 "execution_count": 37,
1048 "metadata": {
1049 "collapsed": false
1050 },
1051 "outputs": [],
1052 "source": [
1053 "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)\n",
1054 "assert(wheel_3.position == 1)\n",
1055 "assert(wheel_3.peg_positions == [20])\n",
1056 "assert(wheel_3.position_l == 'b')\n",
1057 "wheel_3.advance()\n",
1058 "assert(wheel_3.position == 2)\n",
1059 "assert(wheel_3.peg_positions == [19])\n",
1060 "assert(wheel_3.position_l == 'c')"
1061 ]
1062 },
1063 {
1064 "cell_type": "code",
1065 "execution_count": 38,
1066 "metadata": {
1067 "collapsed": false
1068 },
1069 "outputs": [],
1070 "source": [
1071 "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n",
1072 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n",
1073 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n",
1074 "assert(wheel_6.position == 25)\n",
1075 "assert(11 in wheel_6.peg_positions)\n",
1076 "assert(24 in wheel_6.peg_positions)\n",
1077 "assert(wheel_6.position_l == 'b')\n",
1078 "\n",
1079 "wheel_6.advance()\n",
1080 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n",
1081 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n",
1082 "assert(wheel_6.position == 0)\n",
1083 "assert(10 in wheel_6.peg_positions)\n",
1084 "assert(23 in wheel_6.peg_positions)\n",
1085 "assert(wheel_6.position_l == 'c')\n",
1086 "\n",
1087 "for _ in range(22): wheel_6.advance()\n",
1088 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'mgxantkzsyqjcufirldvhoewbp')\n",
1089 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'dymswobuplgraevzkqifntxcjh')\n",
1090 "assert(wheel_6.position == 22)\n",
1091 "assert(1 in wheel_6.peg_positions)\n",
1092 "assert(14 in wheel_6.peg_positions)\n",
1093 "assert(wheel_6.position_l == 'y')\n",
1094 "\n",
1095 "wheel_6.advance()\n",
1096 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'fwzmsjyrxpibtehqkcugndvaol')\n",
1097 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'xlrvnatokfqzduyjphemswbigc')\n",
1098 "assert(wheel_6.position == 23)\n",
1099 "assert(0 in wheel_6.peg_positions)\n",
1100 "assert(13 in wheel_6.peg_positions)\n",
1101 "assert(wheel_6.position_l == 'z')\n",
1102 "\n",
1103 "wheel_6.advance()\n",
1104 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'vylrixqwohasdgpjbtfmcuznke')\n",
1105 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'kqumzsnjepyctxiogdlrvahfbw')\n",
1106 "assert(wheel_6.position == 24)\n",
1107 "assert(25 in wheel_6.peg_positions)\n",
1108 "assert(12 in wheel_6.peg_positions)\n",
1109 "assert(wheel_6.position_l == 'a')\n",
1110 "\n",
1111 "wheel_6.advance()\n",
1112 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n",
1113 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n",
1114 "assert(wheel_6.position == 25)\n",
1115 "assert(24 in wheel_6.peg_positions)\n",
1116 "assert(11 in wheel_6.peg_positions)\n",
1117 "assert(wheel_6.position_l == 'b')\n",
1118 "\n",
1119 "wheel_6.advance()\n",
1120 "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n",
1121 "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n",
1122 "assert(wheel_6.position == 0)\n",
1123 "assert(23 in wheel_6.peg_positions)\n",
1124 "assert(10 in wheel_6.peg_positions)\n",
1125 "assert(wheel_6.position_l == 'c')"
1126 ]
1127 },
1128 {
1129 "cell_type": "code",
1130 "execution_count": 39,
1131 "metadata": {
1132 "collapsed": false
1133 },
1134 "outputs": [
1135 {
1136 "data": {
1137 "text/plain": [
1138 "(0, 'c', [23, 10])"
1139 ]
1140 },
1141 "execution_count": 39,
1142 "metadata": {},
1143 "output_type": "execute_result"
1144 }
1145 ],
1146 "source": [
1147 "wheel_6.position, wheel_6.position_l, wheel_6.peg_positions"
1148 ]
1149 },
1150 {
1151 "cell_type": "code",
1152 "execution_count": 40,
1153 "metadata": {
1154 "collapsed": true
1155 },
1156 "outputs": [],
1157 "source": [
1158 "class Enigma(object):\n",
1159 " def __init__(self, reflector_spec,\n",
1160 " left_wheel_spec, left_wheel_pegs,\n",
1161 " middle_wheel_spec, middle_wheel_pegs,\n",
1162 " right_wheel_spec, right_wheel_pegs,\n",
1163 " left_ring_setting, middle_ring_setting, right_ring_setting,\n",
1164 " plugboard_setting):\n",
1165 " self.reflector = Reflector(reflector_spec)\n",
1166 " self.left_wheel = Wheel(left_wheel_spec, left_wheel_pegs, ring_setting=left_ring_setting)\n",
1167 " self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_pegs, ring_setting=middle_ring_setting)\n",
1168 " self.right_wheel = Wheel(right_wheel_spec, right_wheel_pegs, ring_setting=right_ring_setting)\n",
1169 " self.plugboard = Plugboard(plugboard_setting)\n",
1170 " \n",
1171 " def __getattribute__(self,name):\n",
1172 " if name=='wheel_positions':\n",
1173 " return self.left_wheel.position, self.middle_wheel.position, self.right_wheel.position \n",
1174 " elif name=='wheel_positions_l':\n",
1175 " return self.left_wheel.position_l, self.middle_wheel.position_l, self.right_wheel.position_l \n",
1176 " elif name=='peg_positions':\n",
1177 " return self.left_wheel.peg_positions, self.middle_wheel.peg_positions, self.right_wheel.peg_positions\n",
1178 " else:\n",
1179 " return object.__getattribute__(self, name)\n",
1180 "\n",
1181 " \n",
1182 " def set_wheels(self, left_wheel_position, middle_wheel_position, right_wheel_position):\n",
1183 " self.left_wheel.set_position(left_wheel_position)\n",
1184 " self.middle_wheel.set_position(middle_wheel_position)\n",
1185 " self.right_wheel.set_position(right_wheel_position)\n",
1186 " \n",
1187 " def lookup(self, letter):\n",
1188 " a = self.plugboard.forward(letter)\n",
1189 " b = self.right_wheel.forward(a)\n",
1190 " c = self.middle_wheel.forward(b)\n",
1191 " d = self.left_wheel.forward(c)\n",
1192 " e = self.reflector.forward(d)\n",
1193 " f = self.left_wheel.backward(e)\n",
1194 " g = self.middle_wheel.backward(f)\n",
1195 " h = self.right_wheel.backward(g)\n",
1196 " i = self.plugboard.backward(h)\n",
1197 " return i\n",
1198 " \n",
1199 " def advance(self):\n",
1200 " advance_middle = False\n",
1201 " advance_left = False\n",
1202 " if 0 in self.right_wheel.peg_positions:\n",
1203 " advance_middle = True\n",
1204 " if 0 in self.middle_wheel.peg_positions:\n",
1205 " advance_left = True\n",
1206 " advance_middle = True\n",
1207 " self.right_wheel.advance()\n",
1208 " if advance_middle: self.middle_wheel.advance()\n",
1209 " if advance_left: self.left_wheel.advance()\n",
1210 " \n",
1211 " def encipher_letter(self, letter):\n",
1212 " self.advance()\n",
1213 " return self.lookup(letter)\n",
1214 " \n",
1215 " def encipher(self, message):\n",
1216 " enciphered = ''\n",
1217 " for letter in clean(message):\n",
1218 " enciphered += self.encipher_letter(letter)\n",
1219 " return enciphered"
1220 ]
1221 },
1222 {
1223 "cell_type": "code",
1224 "execution_count": 41,
1225 "metadata": {
1226 "collapsed": false
1227 },
1228 "outputs": [],
1229 "source": [
1230 "enigma = Enigma(reflector_b_spec, \n",
1231 " wheel_i_spec, wheel_i_pegs,\n",
1232 " wheel_ii_spec, wheel_ii_pegs,\n",
1233 " wheel_iii_spec, wheel_iii_pegs,\n",
1234 " 1, 1, 1,\n",
1235 " '')"
1236 ]
1237 },
1238 {
1239 "cell_type": "code",
1240 "execution_count": 42,
1241 "metadata": {
1242 "collapsed": false
1243 },
1244 "outputs": [
1245 {
1246 "data": {
1247 "text/plain": [
1248 "'u'"
1249 ]
1250 },
1251 "execution_count": 42,
1252 "metadata": {},
1253 "output_type": "execute_result"
1254 }
1255 ],
1256 "source": [
1257 "enigma.lookup('a')"
1258 ]
1259 },
1260 {
1261 "cell_type": "code",
1262 "execution_count": 43,
1263 "metadata": {
1264 "collapsed": false
1265 },
1266 "outputs": [
1267 {
1268 "data": {
1269 "text/plain": [
1270 "'a'"
1271 ]
1272 },
1273 "execution_count": 43,
1274 "metadata": {},
1275 "output_type": "execute_result"
1276 }
1277 ],
1278 "source": [
1279 "enigma.lookup('u')"
1280 ]
1281 },
1282 {
1283 "cell_type": "code",
1284 "execution_count": 44,
1285 "metadata": {
1286 "collapsed": false
1287 },
1288 "outputs": [
1289 {
1290 "data": {
1291 "text/plain": [
1292 "'uejobtpzwcnsrkdgvmlfaqiyxh'"
1293 ]
1294 },
1295 "execution_count": 44,
1296 "metadata": {},
1297 "output_type": "execute_result"
1298 }
1299 ],
1300 "source": [
1301 "cat(enigma.lookup(l) for l in string.ascii_lowercase)"
1302 ]
1303 },
1304 {
1305 "cell_type": "code",
1306 "execution_count": 45,
1307 "metadata": {
1308 "collapsed": false,
1309 "scrolled": true
1310 },
1311 "outputs": [
1312 {
1313 "name": "stdout",
1314 "output_type": "stream",
1315 "text": [
1316 "0 :: a a a ; [16] [4] [21] uejobtpzwcnsrkdgvmlfaqiyxh\n",
1317 "1 :: a a b ; [16] [4] [20] baqmfexihswpdytlcvjozrkgnu\n",
1318 "2 :: a a c ; [16] [4] [19] djralkwpobfeyqihncxzvugsmt\n",
1319 "3 :: a a d ; [16] [4] [18] zlejcuitgdmbkonsvxphfqyrwa\n",
1320 "4 :: a a e ; [16] [4] [17] gcblwtakqzhdosmxiunfryepvj\n",
1321 "5 :: a a f ; [16] [4] [16] osnirgfmdpvuhcajwebxlkqtzy\n",
1322 "6 :: a a g ; [16] [4] [15] wymvnqzjlhoicekuftxrpdasbg\n",
1323 "7 :: a a h ; [16] [4] [14] cjafkdztpbeuormiwnvhlsqyxg\n",
1324 "8 :: a a i ; [16] [4] [13] xijuyslvbczgnmqwotfrdhpaek\n",
1325 "9 :: a a j ; [16] [4] [12] lfzrwbytjisaovmuxdkhpneqgc\n",
1326 "10 :: a a k ; [16] [4] [11] tkezcqynuwbpvhslfxoaimjrgd\n",
1327 "11 :: a a l ; [16] [4] [10] kiwfnduxbsaotelqpvjmgrchzy\n",
1328 "12 :: a a m ; [16] [4] [9] sfkutbpoxycrnmhgwlaedzqijv\n",
1329 "13 :: a a n ; [16] [4] [8] baqwlkhgrsfextpocijnvudmzy\n",
1330 "14 :: a a o ; [16] [4] [7] teofbdzxqkjyrscvimnawpuhlg\n",
1331 "15 :: a a p ; [16] [4] [6] mhypswrbzxqvaondkgeutlfjci\n",
1332 "16 :: a a q ; [16] [4] [5] cpasnrhgkuixzevbyfdwjotlqm\n",
1333 "17 :: a a r ; [16] [4] [4] dlfatcjwygvbnmzrxpueskhqio\n",
1334 "18 :: a a s ; [16] [4] [3] lxymzjuqtfpadsrkhonigwvbce\n",
1335 "19 :: a a t ; [16] [4] [2] puvioztjdhxmlyeawsrgbcqknf\n",
1336 "20 :: a a u ; [16] [4] [1] baigpldqcowfyzjehvtsxrkumn\n",
1337 "21 :: a a v ; [16] [4] [0] mnvfydiwgzsoablrxpkutchqej\n",
1338 "22 :: a b w ; [16] [3] [25] ulfopcykswhbzvderqixanjtgm\n",
1339 "23 :: a b x ; [16] [3] [24] qmwftdyovursbzhxaklejicpgn\n",
1340 "24 :: a b y ; [16] [3] [23] oljmzxrvucybdqasngpwihtfke\n",
1341 "25 :: a b z ; [16] [3] [22] fwevcalzxutgysrqponkjdbimh\n"
1342 ]
1343 }
1344 ],
1345 "source": [
1346 "enigma.set_wheels('a', 'a', 'a')\n",
1347 "for i in range(26):\n",
1348 " print(i, '::', \n",
1349 " enigma.left_wheel.position_l, enigma.middle_wheel.position_l, enigma.right_wheel.position_l, ';',\n",
1350 " enigma.left_wheel.peg_positions, enigma.middle_wheel.peg_positions, enigma.right_wheel.peg_positions, \n",
1351 " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n",
1352 " enigma.advance()"
1353 ]
1354 },
1355 {
1356 "cell_type": "code",
1357 "execution_count": 46,
1358 "metadata": {
1359 "collapsed": false,
1360 "scrolled": true
1361 },
1362 "outputs": [],
1363 "source": [
1364 "enigma.set_wheels('a', 'a', 't')\n",
1365 "assert(enigma.wheel_positions == (0, 0, 19))\n",
1366 "assert(cat(enigma.wheel_positions_l) == 'aat')\n",
1367 "assert(enigma.peg_positions == ([16], [4], [2]))\n",
1368 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'puvioztjdhxmlyeawsrgbcqknf')\n",
1369 "\n",
1370 "enigma.advance()\n",
1371 "assert(enigma.wheel_positions == (0, 0, 20))\n",
1372 "assert(cat(enigma.wheel_positions_l) == 'aau')\n",
1373 "assert(enigma.peg_positions == ([16], [4], [1]))\n",
1374 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baigpldqcowfyzjehvtsxrkumn')\n",
1375 "\n",
1376 "enigma.advance()\n",
1377 "assert(enigma.wheel_positions == (0, 0, 21))\n",
1378 "assert(cat(enigma.wheel_positions_l) == 'aav')\n",
1379 "assert(enigma.peg_positions == ([16], [4], [0]))\n",
1380 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mnvfydiwgzsoablrxpkutchqej')\n",
1381 "\n",
1382 "enigma.advance()\n",
1383 "assert(enigma.wheel_positions == (0, 1, 22))\n",
1384 "assert(cat(enigma.wheel_positions_l) == 'abw')\n",
1385 "assert(enigma.peg_positions == ([16], [3], [25]))\n",
1386 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ulfopcykswhbzvderqixanjtgm')\n",
1387 "\n",
1388 "enigma.advance()\n",
1389 "assert(enigma.wheel_positions == (0, 1, 23))\n",
1390 "assert(cat(enigma.wheel_positions_l) == 'abx')\n",
1391 "assert(enigma.peg_positions == ([16], [3], [24]))\n",
1392 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qmwftdyovursbzhxaklejicpgn')\n",
1393 "\n",
1394 "enigma.advance()\n",
1395 "assert(enigma.wheel_positions == (0, 1, 24))\n",
1396 "assert(cat(enigma.wheel_positions_l) == 'aby')\n",
1397 "assert(enigma.peg_positions == ([16], [3], [23]))\n",
1398 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'oljmzxrvucybdqasngpwihtfke')\n"
1399 ]
1400 },
1401 {
1402 "cell_type": "code",
1403 "execution_count": 47,
1404 "metadata": {
1405 "collapsed": false,
1406 "scrolled": true
1407 },
1408 "outputs": [
1409 {
1410 "name": "stdout",
1411 "output_type": "stream",
1412 "text": [
1413 "(1, 5, 24) ('b', 'f', 'y') ([15], [25], [23]) baknstqzrmcxjdvygiefwoulph\n"
1414 ]
1415 }
1416 ],
1417 "source": [
1418 "enigma.set_wheels('a', 'd', 't')\n",
1419 "assert(enigma.wheel_positions == (0, 3, 19))\n",
1420 "assert(cat(enigma.wheel_positions_l) == 'adt')\n",
1421 "assert(enigma.peg_positions == ([16], [1], [2]))\n",
1422 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zcbpqxwsjiuonmldethrkygfva')\n",
1423 "\n",
1424 "enigma.advance()\n",
1425 "assert(enigma.wheel_positions == (0, 3, 20))\n",
1426 "assert(cat(enigma.wheel_positions_l) == 'adu')\n",
1427 "assert(enigma.peg_positions == ([16], [1], [1]))\n",
1428 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ehprawjbngotxikcsdqlzyfmvu')\n",
1429 "\n",
1430 "enigma.advance()\n",
1431 "assert(enigma.wheel_positions == (0, 3, 21))\n",
1432 "assert(cat(enigma.wheel_positions_l) == 'adv')\n",
1433 "assert(enigma.peg_positions == ([16], [1], [0]))\n",
1434 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'eqzxarpihmnvjkwgbfuyslodtc')\n",
1435 "\n",
1436 "enigma.advance()\n",
1437 "assert(enigma.wheel_positions == (0, 4, 22))\n",
1438 "assert(cat(enigma.wheel_positions_l) == 'aew')\n",
1439 "assert(enigma.peg_positions == ([16], [0], [25]))\n",
1440 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qedcbtpluzmhkongavwfirsyxj')\n",
1441 "\n",
1442 "enigma.advance()\n",
1443 "assert(enigma.wheel_positions == (1, 5, 23))\n",
1444 "assert(cat(enigma.wheel_positions_l) == 'bfx')\n",
1445 "assert(enigma.peg_positions == ([15], [25], [24]))\n",
1446 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwuedhsfazqxytvrkpgncoblmj')\n",
1447 "\n",
1448 "enigma.advance()\n",
1449 "assert(enigma.wheel_positions == (1, 5, 24))\n",
1450 "assert(cat(enigma.wheel_positions_l) == 'bfy')\n",
1451 "assert(enigma.peg_positions == ([15], [25], [23]))\n",
1452 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baknstqzrmcxjdvygiefwoulph')\n",
1453 "\n",
1454 "print(enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, \n",
1455 " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n"
1456 ]
1457 },
1458 {
1459 "cell_type": "code",
1460 "execution_count": 48,
1461 "metadata": {
1462 "collapsed": false
1463 },
1464 "outputs": [
1465 {
1466 "data": {
1467 "text/plain": [
1468 "'olpfhnvflyn'"
1469 ]
1470 },
1471 "execution_count": 48,
1472 "metadata": {},
1473 "output_type": "execute_result"
1474 }
1475 ],
1476 "source": [
1477 "enigma.set_wheels('a', 'a', 'a')\n",
1478 "ct = enigma.encipher('testmessage')\n",
1479 "assert(ct == 'olpfhnvflyn')\n",
1480 "ct"
1481 ]
1482 },
1483 {
1484 "cell_type": "code",
1485 "execution_count": 49,
1486 "metadata": {
1487 "collapsed": false
1488 },
1489 "outputs": [
1490 {
1491 "data": {
1492 "text/plain": [
1493 "'lawnjgpwjik'"
1494 ]
1495 },
1496 "execution_count": 49,
1497 "metadata": {},
1498 "output_type": "execute_result"
1499 }
1500 ],
1501 "source": [
1502 "enigma.set_wheels('a', 'd', 't')\n",
1503 "ct = enigma.encipher('testmessage')\n",
1504 "assert(ct == 'lawnjgpwjik')\n",
1505 "ct"
1506 ]
1507 },
1508 {
1509 "cell_type": "code",
1510 "execution_count": 50,
1511 "metadata": {
1512 "collapsed": false
1513 },
1514 "outputs": [
1515 {
1516 "name": "stdout",
1517 "output_type": "stream",
1518 "text": [
1519 "enigma.advance()\n",
1520 "assert(enigma.wheel_positions == (1, 5, 5))\n",
1521 "assert(cat(enigma.wheel_positions_l) == 'bff')\n",
1522 "assert(enigma.peg_positions == ([15], [25], [16]))\n",
1523 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zpqiogfsdlmjkyebcvhxwrutna')\n",
1524 "\n",
1525 "enigma.advance()\n",
1526 "assert(enigma.wheel_positions == (1, 5, 6))\n",
1527 "assert(cat(enigma.wheel_positions_l) == 'bfg')\n",
1528 "assert(enigma.peg_positions == ([15], [25], [15]))\n",
1529 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fjmnwayslbxicdpouthrqzekgv')\n",
1530 "\n",
1531 "enigma.advance()\n",
1532 "assert(enigma.wheel_positions == (1, 5, 7))\n",
1533 "assert(cat(enigma.wheel_positions_l) == 'bfh')\n",
1534 "assert(enigma.peg_positions == ([15], [25], [14]))\n",
1535 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'csafzdyloxuhnmitwvbpkrqjge')\n",
1536 "\n",
1537 "enigma.advance()\n",
1538 "assert(enigma.wheel_positions == (1, 5, 8))\n",
1539 "assert(cat(enigma.wheel_positions_l) == 'bfi')\n",
1540 "assert(enigma.peg_positions == ([15], [25], [13]))\n",
1541 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'kihyvulcbtagwrqzonxjfemsdp')\n",
1542 "\n",
1543 "enigma.advance()\n",
1544 "assert(enigma.wheel_positions == (1, 5, 9))\n",
1545 "assert(cat(enigma.wheel_positions_l) == 'bfj')\n",
1546 "assert(enigma.peg_positions == ([15], [25], [12]))\n",
1547 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pgzrytbksqhwxvuajdifonlmec')\n",
1548 "\n",
1549 "enigma.advance()\n",
1550 "assert(enigma.wheel_positions == (1, 5, 10))\n",
1551 "assert(cat(enigma.wheel_positions_l) == 'bfk')\n",
1552 "assert(enigma.peg_positions == ([15], [25], [11]))\n",
1553 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fkirsazncwbvyhpoudexqljtmg')\n",
1554 "\n",
1555 "enigma.advance()\n",
1556 "assert(enigma.wheel_positions == (1, 5, 11))\n",
1557 "assert(cat(enigma.wheel_positions_l) == 'bfl')\n",
1558 "assert(enigma.peg_positions == ([15], [25], [10]))\n",
1559 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mhkronubsvctafeqpdilgjxwzy')\n",
1560 "\n",
1561 "enigma.advance()\n",
1562 "assert(enigma.wheel_positions == (1, 5, 12))\n",
1563 "assert(cat(enigma.wheel_positions_l) == 'bfm')\n",
1564 "assert(enigma.peg_positions == ([15], [25], [9]))\n",
1565 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'gnkuoxarzycmlbetvhwpdqsfji')\n",
1566 "\n",
1567 "enigma.advance()\n",
1568 "assert(enigma.wheel_positions == (1, 5, 13))\n",
1569 "assert(cat(enigma.wheel_positions_l) == 'bfn')\n",
1570 "assert(enigma.peg_positions == ([15], [25], [8]))\n",
1571 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bainslqkcxhfudpogtermwvjzy')\n",
1572 "\n",
1573 "enigma.advance()\n",
1574 "assert(enigma.wheel_positions == (1, 5, 14))\n",
1575 "assert(cat(enigma.wheel_positions_l) == 'bfo')\n",
1576 "assert(enigma.peg_positions == ([15], [25], [7]))\n",
1577 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xemfbdnwjitycgzusvqkprhalo')\n",
1578 "\n",
1579 "enigma.advance()\n",
1580 "assert(enigma.wheel_positions == (1, 5, 15))\n",
1581 "assert(cat(enigma.wheel_positions_l) == 'bfp')\n",
1582 "assert(enigma.peg_positions == ([15], [25], [6]))\n",
1583 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qixksmhgbtdvfonrapejwluczy')\n",
1584 "\n",
1585 "enigma.advance()\n",
1586 "assert(enigma.wheel_positions == (1, 5, 16))\n",
1587 "assert(cat(enigma.wheel_positions_l) == 'bfq')\n",
1588 "assert(enigma.peg_positions == ([15], [25], [5]))\n",
1589 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cgaulmbskwiefrtzynhodxjvqp')\n",
1590 "\n",
1591 "enigma.advance()\n",
1592 "assert(enigma.wheel_positions == (1, 5, 17))\n",
1593 "assert(cat(enigma.wheel_positions_l) == 'bfr')\n",
1594 "assert(enigma.peg_positions == ([15], [25], [4]))\n",
1595 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwqfldszaxvenmyrcpgutkbjoh')\n",
1596 "\n",
1597 "enigma.advance()\n",
1598 "assert(enigma.wheel_positions == (1, 5, 18))\n",
1599 "assert(cat(enigma.wheel_positions_l) == 'bfs')\n",
1600 "assert(enigma.peg_positions == ([15], [25], [3]))\n",
1601 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vxykrjilgfdhqtusmepnoazbcw')\n",
1602 "\n",
1603 "enigma.advance()\n",
1604 "assert(enigma.wheel_positions == (1, 5, 19))\n",
1605 "assert(cat(enigma.wheel_positions_l) == 'bft')\n",
1606 "assert(enigma.peg_positions == ([15], [25], [2]))\n",
1607 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ieysbvkjahgmlpxnwtdrzfqocu')\n",
1608 "\n",
1609 "enigma.advance()\n",
1610 "assert(enigma.wheel_positions == (1, 5, 20))\n",
1611 "assert(cat(enigma.wheel_positions_l) == 'bfu')\n",
1612 "assert(enigma.peg_positions == ([15], [25], [1]))\n",
1613 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baihkjvdcfepywsltxoqzgnrmu')\n",
1614 "\n",
1615 "enigma.advance()\n",
1616 "assert(enigma.wheel_positions == (1, 5, 21))\n",
1617 "assert(cat(enigma.wheel_positions_l) == 'bfv')\n",
1618 "assert(enigma.peg_positions == ([15], [25], [0]))\n",
1619 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bayjtrilgdshvzuwxfkeompqcn')\n",
1620 "\n",
1621 "enigma.advance()\n",
1622 "assert(enigma.wheel_positions == (1, 6, 22))\n",
1623 "assert(cat(enigma.wheel_positions_l) == 'bgw')\n",
1624 "assert(enigma.peg_positions == ([15], [24], [25]))\n",
1625 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'rszqohpfxyutvwegdablkmnijc')\n",
1626 "\n",
1627 "enigma.advance()\n",
1628 "assert(enigma.wheel_positions == (1, 6, 23))\n",
1629 "assert(cat(enigma.wheel_positions_l) == 'bgx')\n",
1630 "assert(enigma.peg_positions == ([15], [24], [24]))\n",
1631 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nfoxhbzeyrwqpacmljtsvukdig')\n",
1632 "\n",
1633 "enigma.advance()\n",
1634 "assert(enigma.wheel_positions == (1, 6, 24))\n",
1635 "assert(cat(enigma.wheel_positions_l) == 'bgy')\n",
1636 "assert(enigma.peg_positions == ([15], [24], [23]))\n",
1637 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'czaogmeihtuqfsdxlwnjkyrpvb')\n",
1638 "\n",
1639 "enigma.advance()\n",
1640 "assert(enigma.wheel_positions == (1, 6, 25))\n",
1641 "assert(cat(enigma.wheel_positions_l) == 'bgz')\n",
1642 "assert(enigma.peg_positions == ([15], [24], [22]))\n",
1643 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'omwgysdjkhizbxarupfvqtcnel')\n",
1644 "\n",
1645 "enigma.advance()\n",
1646 "assert(enigma.wheel_positions == (1, 6, 0))\n",
1647 "assert(cat(enigma.wheel_positions_l) == 'bga')\n",
1648 "assert(enigma.peg_positions == ([15], [24], [21]))\n",
1649 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cxafmdrzoqutepinjgvlksybwh')\n",
1650 "\n",
1651 "enigma.advance()\n",
1652 "assert(enigma.wheel_positions == (1, 6, 1))\n",
1653 "assert(cat(enigma.wheel_positions_l) == 'bgb')\n",
1654 "assert(enigma.peg_positions == ([15], [24], [20]))\n",
1655 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'jymvnrxkoahwceiuzftspdlgbq')\n",
1656 "\n",
1657 "enigma.advance()\n",
1658 "assert(enigma.wheel_positions == (1, 6, 2))\n",
1659 "assert(cat(enigma.wheel_positions_l) == 'bgc')\n",
1660 "assert(enigma.peg_positions == ([15], [24], [19]))\n",
1661 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'uzlyiqwrestcnmxvfhjkapgodb')\n",
1662 "\n",
1663 "enigma.advance()\n",
1664 "assert(enigma.wheel_positions == (1, 6, 3))\n",
1665 "assert(cat(enigma.wheel_positions_l) == 'bgd')\n",
1666 "assert(enigma.peg_positions == ([15], [24], [18]))\n",
1667 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'veosbuhgpzqynmcikwdxfartlj')\n",
1668 "\n",
1669 "enigma.advance()\n",
1670 "assert(enigma.wheel_positions == (1, 6, 4))\n",
1671 "assert(cat(enigma.wheel_positions_l) == 'bge')\n",
1672 "assert(enigma.peg_positions == ([15], [24], [17]))\n",
1673 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ydhbmtrclxsiezpougkfqwvjan')\n",
1674 "\n"
1675 ]
1676 }
1677 ],
1678 "source": [
1679 "\n",
1680 "for i in range(26):\n",
1681 " enigma.advance()\n",
1682 " print('enigma.advance()')\n",
1683 " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n",
1684 " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n",
1685 " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n",
1686 " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n",
1687 " print()"
1688 ]
1689 },
1690 {
1691 "cell_type": "code",
1692 "execution_count": 51,
1693 "metadata": {
1694 "collapsed": false
1695 },
1696 "outputs": [
1697 {
1698 "data": {
1699 "text/plain": [
1700 "'bahxvfrpdc'"
1701 ]
1702 },
1703 "execution_count": 51,
1704 "metadata": {},
1705 "output_type": "execute_result"
1706 }
1707 ],
1708 "source": [
1709 "enigma.set_wheels('a', 'd', 't')\n",
1710 "ct = enigma.encipher('hellothere')\n",
1711 "assert(ct == 'bahxvfrpdc')\n",
1712 "ct"
1713 ]
1714 },
1715 {
1716 "cell_type": "code",
1717 "execution_count": 52,
1718 "metadata": {
1719 "collapsed": false
1720 },
1721 "outputs": [
1722 {
1723 "data": {
1724 "text/plain": [
1725 "'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr'"
1726 ]
1727 },
1728 "execution_count": 52,
1729 "metadata": {},
1730 "output_type": "execute_result"
1731 }
1732 ],
1733 "source": [
1734 "enigma.set_wheels('b', 'd', 'q')\n",
1735 "ct = enigma.encipher('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')\n",
1736 "assert(ct == 'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr')\n",
1737 "assert(enigma.left_wheel.position_l == 'c')\n",
1738 "assert(enigma.middle_wheel.position_l == 'h')\n",
1739 "assert(enigma.right_wheel.position_l == 'a')\n",
1740 "ct"
1741 ]
1742 },
1743 {
1744 "cell_type": "code",
1745 "execution_count": 53,
1746 "metadata": {
1747 "collapsed": false
1748 },
1749 "outputs": [
1750 {
1751 "data": {
1752 "text/plain": [
1753 "'c'"
1754 ]
1755 },
1756 "execution_count": 53,
1757 "metadata": {},
1758 "output_type": "execute_result"
1759 }
1760 ],
1761 "source": [
1762 "enigma.left_wheel.position_l"
1763 ]
1764 },
1765 {
1766 "cell_type": "code",
1767 "execution_count": 54,
1768 "metadata": {
1769 "collapsed": true
1770 },
1771 "outputs": [],
1772 "source": [
1773 "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n",
1774 "# Enigma simulation settings are \n",
1775 "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n",
1776 "w_enigma = Enigma(reflector_b_spec, \n",
1777 " wheel_i_spec, wheel_i_pegs,\n",
1778 " wheel_v_spec, wheel_v_pegs,\n",
1779 " wheel_iii_spec, wheel_iii_pegs,\n",
1780 " 6, 20, 24,\n",
1781 " 'ua pf rq so ni ey bg hl tx zj')"
1782 ]
1783 },
1784 {
1785 "cell_type": "code",
1786 "execution_count": 55,
1787 "metadata": {
1788 "collapsed": true
1789 },
1790 "outputs": [],
1791 "source": [
1792 "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n",
1793 "# Enigma simulation settings are \n",
1794 "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n",
1795 "enigma = Enigma(reflector_b_spec, \n",
1796 " wheel_i_spec, wheel_i_pegs,\n",
1797 " wheel_v_spec, wheel_v_pegs,\n",
1798 " wheel_iii_spec, wheel_iii_pegs,\n",
1799 " 6, 20, 24,\n",
1800 " 'ua pf rq so ni ey bg hl tx zj')"
1801 ]
1802 },
1803 {
1804 "cell_type": "code",
1805 "execution_count": 56,
1806 "metadata": {
1807 "collapsed": true
1808 },
1809 "outputs": [],
1810 "source": [
1811 "enigma.set_wheels('j', 'e', 'u')\n",
1812 "\n",
1813 "enigma.advance()\n",
1814 "assert(enigma.wheel_positions == (4, 11, 24))\n",
1815 "assert(cat(enigma.wheel_positions_l) == 'jev')\n",
1816 "assert(enigma.peg_positions == ([7], [21], [0]))\n",
1817 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mvqjlyowkdieasgzcunxrbhtfp')\n",
1818 "\n",
1819 "enigma.advance()\n",
1820 "assert(enigma.wheel_positions == (4, 12, 25))\n",
1821 "assert(cat(enigma.wheel_positions_l) == 'jfw')\n",
1822 "assert(enigma.peg_positions == ([7], [20], [25]))\n",
1823 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'sjolzuyvrbwdpxcmtiaqfhknge')\n",
1824 "\n",
1825 "enigma.advance()\n",
1826 "assert(enigma.wheel_positions == (4, 12, 0))\n",
1827 "assert(cat(enigma.wheel_positions_l) == 'jfx')\n",
1828 "assert(enigma.peg_positions == ([7], [20], [24]))\n",
1829 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qrxedkoywufmlvgsabpzjnicht')\n",
1830 "\n",
1831 "enigma.advance()\n",
1832 "assert(enigma.wheel_positions == (4, 12, 1))\n",
1833 "assert(cat(enigma.wheel_positions_l) == 'jfy')\n",
1834 "assert(enigma.peg_positions == ([7], [20], [23]))\n",
1835 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hpsukliagqefwvtbjxcodnmrzy')\n",
1836 "\n",
1837 "enigma.advance()\n",
1838 "assert(enigma.wheel_positions == (4, 12, 2))\n",
1839 "assert(cat(enigma.wheel_positions_l) == 'jfz')\n",
1840 "assert(enigma.peg_positions == ([7], [20], [22]))\n",
1841 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zevnbpyqowrtxdifhkulscjmga')\n"
1842 ]
1843 },
1844 {
1845 "cell_type": "code",
1846 "execution_count": 57,
1847 "metadata": {
1848 "collapsed": true
1849 },
1850 "outputs": [],
1851 "source": [
1852 "enigma.set_wheels('i', 'd', 'z')\n",
1853 "\n",
1854 "enigma.advance()\n",
1855 "assert(enigma.wheel_positions == (3, 10, 3))\n",
1856 "assert(cat(enigma.wheel_positions_l) == 'ida')\n",
1857 "assert(enigma.peg_positions == ([8], [22], [21]))\n",
1858 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n",
1859 "\n",
1860 "enigma.advance()\n",
1861 "assert(enigma.wheel_positions == (3, 10, 4))\n",
1862 "assert(cat(enigma.wheel_positions_l) == 'idb')\n",
1863 "assert(enigma.peg_positions == ([8], [22], [20]))\n",
1864 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n",
1865 "\n",
1866 "enigma.advance()\n",
1867 "assert(enigma.wheel_positions == (3, 10, 5))\n",
1868 "assert(cat(enigma.wheel_positions_l) == 'idc')\n",
1869 "assert(enigma.peg_positions == ([8], [22], [19]))\n",
1870 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n",
1871 "\n",
1872 "enigma.advance()\n",
1873 "assert(enigma.wheel_positions == (3, 10, 6))\n",
1874 "assert(cat(enigma.wheel_positions_l) == 'idd')\n",
1875 "assert(enigma.peg_positions == ([8], [22], [18]))\n",
1876 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n",
1877 "\n",
1878 "enigma.advance()\n",
1879 "assert(enigma.wheel_positions == (3, 10, 7))\n",
1880 "assert(cat(enigma.wheel_positions_l) == 'ide')\n",
1881 "assert(enigma.peg_positions == ([8], [22], [17]))\n",
1882 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n",
1883 "\n",
1884 "enigma.advance()\n",
1885 "assert(enigma.wheel_positions == (3, 10, 8))\n",
1886 "assert(cat(enigma.wheel_positions_l) == 'idf')\n",
1887 "assert(enigma.peg_positions == ([8], [22], [16]))\n",
1888 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n",
1889 "\n",
1890 "enigma.advance()\n",
1891 "assert(enigma.wheel_positions == (3, 10, 9))\n",
1892 "assert(cat(enigma.wheel_positions_l) == 'idg')\n",
1893 "assert(enigma.peg_positions == ([8], [22], [15]))\n",
1894 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n",
1895 "\n",
1896 "enigma.advance()\n",
1897 "assert(enigma.wheel_positions == (3, 10, 10))\n",
1898 "assert(cat(enigma.wheel_positions_l) == 'idh')\n",
1899 "assert(enigma.peg_positions == ([8], [22], [14]))\n",
1900 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n",
1901 "\n",
1902 "enigma.advance()\n",
1903 "assert(enigma.wheel_positions == (3, 10, 11))\n",
1904 "assert(cat(enigma.wheel_positions_l) == 'idi')\n",
1905 "assert(enigma.peg_positions == ([8], [22], [13]))\n",
1906 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n",
1907 "\n",
1908 "enigma.advance()\n",
1909 "assert(enigma.wheel_positions == (3, 10, 12))\n",
1910 "assert(cat(enigma.wheel_positions_l) == 'idj')\n",
1911 "assert(enigma.peg_positions == ([8], [22], [12]))\n",
1912 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n",
1913 "\n",
1914 "enigma.advance()\n",
1915 "assert(enigma.wheel_positions == (3, 10, 13))\n",
1916 "assert(cat(enigma.wheel_positions_l) == 'idk')\n",
1917 "assert(enigma.peg_positions == ([8], [22], [11]))\n",
1918 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n",
1919 "\n",
1920 "enigma.advance()\n",
1921 "assert(enigma.wheel_positions == (3, 10, 14))\n",
1922 "assert(cat(enigma.wheel_positions_l) == 'idl')\n",
1923 "assert(enigma.peg_positions == ([8], [22], [10]))\n",
1924 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n",
1925 "\n",
1926 "enigma.advance()\n",
1927 "assert(enigma.wheel_positions == (3, 10, 15))\n",
1928 "assert(cat(enigma.wheel_positions_l) == 'idm')\n",
1929 "assert(enigma.peg_positions == ([8], [22], [9]))\n",
1930 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n",
1931 "\n",
1932 "enigma.advance()\n",
1933 "assert(enigma.wheel_positions == (3, 10, 16))\n",
1934 "assert(cat(enigma.wheel_positions_l) == 'idn')\n",
1935 "assert(enigma.peg_positions == ([8], [22], [8]))\n",
1936 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n",
1937 "\n",
1938 "enigma.advance()\n",
1939 "assert(enigma.wheel_positions == (3, 10, 17))\n",
1940 "assert(cat(enigma.wheel_positions_l) == 'ido')\n",
1941 "assert(enigma.peg_positions == ([8], [22], [7]))\n",
1942 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n",
1943 "\n",
1944 "enigma.advance()\n",
1945 "assert(enigma.wheel_positions == (3, 10, 18))\n",
1946 "assert(cat(enigma.wheel_positions_l) == 'idp')\n",
1947 "assert(enigma.peg_positions == ([8], [22], [6]))\n",
1948 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n",
1949 "\n",
1950 "enigma.advance()\n",
1951 "assert(enigma.wheel_positions == (3, 10, 19))\n",
1952 "assert(cat(enigma.wheel_positions_l) == 'idq')\n",
1953 "assert(enigma.peg_positions == ([8], [22], [5]))\n",
1954 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n",
1955 "\n",
1956 "enigma.advance()\n",
1957 "assert(enigma.wheel_positions == (3, 10, 20))\n",
1958 "assert(cat(enigma.wheel_positions_l) == 'idr')\n",
1959 "assert(enigma.peg_positions == ([8], [22], [4]))\n",
1960 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n",
1961 "\n",
1962 "enigma.advance()\n",
1963 "assert(enigma.wheel_positions == (3, 10, 21))\n",
1964 "assert(cat(enigma.wheel_positions_l) == 'ids')\n",
1965 "assert(enigma.peg_positions == ([8], [22], [3]))\n",
1966 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n",
1967 "\n",
1968 "enigma.advance()\n",
1969 "assert(enigma.wheel_positions == (3, 10, 22))\n",
1970 "assert(cat(enigma.wheel_positions_l) == 'idt')\n",
1971 "assert(enigma.peg_positions == ([8], [22], [2]))\n",
1972 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n",
1973 "\n",
1974 "enigma.advance()\n",
1975 "assert(enigma.wheel_positions == (3, 10, 23))\n",
1976 "assert(cat(enigma.wheel_positions_l) == 'idu')\n",
1977 "assert(enigma.peg_positions == ([8], [22], [1]))\n",
1978 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n",
1979 "\n",
1980 "enigma.advance()\n",
1981 "assert(enigma.wheel_positions == (3, 10, 24))\n",
1982 "assert(cat(enigma.wheel_positions_l) == 'idv')\n",
1983 "assert(enigma.peg_positions == ([8], [22], [0]))\n",
1984 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n",
1985 "\n",
1986 "enigma.advance()\n",
1987 "assert(enigma.wheel_positions == (3, 11, 25))\n",
1988 "assert(cat(enigma.wheel_positions_l) == 'iew')\n",
1989 "assert(enigma.peg_positions == ([8], [21], [25]))\n",
1990 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n",
1991 "\n",
1992 "enigma.advance()\n",
1993 "assert(enigma.wheel_positions == (3, 11, 0))\n",
1994 "assert(cat(enigma.wheel_positions_l) == 'iex')\n",
1995 "assert(enigma.peg_positions == ([8], [21], [24]))\n",
1996 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n",
1997 "\n",
1998 "enigma.advance()\n",
1999 "assert(enigma.wheel_positions == (3, 11, 1))\n",
2000 "assert(cat(enigma.wheel_positions_l) == 'iey')\n",
2001 "assert(enigma.peg_positions == ([8], [21], [23]))\n",
2002 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n"
2003 ]
2004 },
2005 {
2006 "cell_type": "code",
2007 "execution_count": 58,
2008 "metadata": {
2009 "collapsed": false
2010 },
2011 "outputs": [
2012 {
2013 "data": {
2014 "text/plain": [
2015 "('verylongtestmessagewithanextrabitofmessageforgoodmeasure',\n",
2016 " (3, 12, 6),\n",
2017 " ('i', 'f', 'd'),\n",
2018 " ([8], [20], [18]),\n",
2019 " 'urygzpdmxtwshqvfnbljaokice')"
2020 ]
2021 },
2022 "execution_count": 58,
2023 "metadata": {},
2024 "output_type": "execute_result"
2025 }
2026 ],
2027 "source": [
2028 "enigma.set_wheels('i', 'd', 'z')\n",
2029 "ct = enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n",
2030 "assert(ct == 'gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n",
2031 "assert(enigma.wheel_positions == (3, 12, 6))\n",
2032 "assert(cat(enigma.wheel_positions_l) == 'ifd')\n",
2033 "assert(enigma.peg_positions == ([8], [20], [18]))\n",
2034 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'urygzpdmxtwshqvfnbljaokice')\n",
2035 "\n",
2036 "enigma.set_wheels('i', 'd', 'z')\n",
2037 "pt = enigma.encipher('gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n",
2038 "assert(pt == 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n",
2039 "\n",
2040 "pt, enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, cat(enigma.lookup(l) for l in string.ascii_lowercase)"
2041 ]
2042 },
2043 {
2044 "cell_type": "code",
2045 "execution_count": 59,
2046 "metadata": {
2047 "collapsed": false
2048 },
2049 "outputs": [
2050 {
2051 "name": "stdout",
2052 "output_type": "stream",
2053 "text": [
2054 "enigma.advance()\n",
2055 "assert(enigma.wheel_positions == (3, 10, 3))\n",
2056 "assert(cat(enigma.wheel_positions_l) == 'ida')\n",
2057 "assert(enigma.peg_positions == ([8], [22], [21]))\n",
2058 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n",
2059 "\n",
2060 "enigma.advance()\n",
2061 "assert(enigma.wheel_positions == (3, 10, 4))\n",
2062 "assert(cat(enigma.wheel_positions_l) == 'idb')\n",
2063 "assert(enigma.peg_positions == ([8], [22], [20]))\n",
2064 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n",
2065 "\n",
2066 "enigma.advance()\n",
2067 "assert(enigma.wheel_positions == (3, 10, 5))\n",
2068 "assert(cat(enigma.wheel_positions_l) == 'idc')\n",
2069 "assert(enigma.peg_positions == ([8], [22], [19]))\n",
2070 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n",
2071 "\n",
2072 "enigma.advance()\n",
2073 "assert(enigma.wheel_positions == (3, 10, 6))\n",
2074 "assert(cat(enigma.wheel_positions_l) == 'idd')\n",
2075 "assert(enigma.peg_positions == ([8], [22], [18]))\n",
2076 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n",
2077 "\n",
2078 "enigma.advance()\n",
2079 "assert(enigma.wheel_positions == (3, 10, 7))\n",
2080 "assert(cat(enigma.wheel_positions_l) == 'ide')\n",
2081 "assert(enigma.peg_positions == ([8], [22], [17]))\n",
2082 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n",
2083 "\n",
2084 "enigma.advance()\n",
2085 "assert(enigma.wheel_positions == (3, 10, 8))\n",
2086 "assert(cat(enigma.wheel_positions_l) == 'idf')\n",
2087 "assert(enigma.peg_positions == ([8], [22], [16]))\n",
2088 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n",
2089 "\n",
2090 "enigma.advance()\n",
2091 "assert(enigma.wheel_positions == (3, 10, 9))\n",
2092 "assert(cat(enigma.wheel_positions_l) == 'idg')\n",
2093 "assert(enigma.peg_positions == ([8], [22], [15]))\n",
2094 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n",
2095 "\n",
2096 "enigma.advance()\n",
2097 "assert(enigma.wheel_positions == (3, 10, 10))\n",
2098 "assert(cat(enigma.wheel_positions_l) == 'idh')\n",
2099 "assert(enigma.peg_positions == ([8], [22], [14]))\n",
2100 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n",
2101 "\n",
2102 "enigma.advance()\n",
2103 "assert(enigma.wheel_positions == (3, 10, 11))\n",
2104 "assert(cat(enigma.wheel_positions_l) == 'idi')\n",
2105 "assert(enigma.peg_positions == ([8], [22], [13]))\n",
2106 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n",
2107 "\n",
2108 "enigma.advance()\n",
2109 "assert(enigma.wheel_positions == (3, 10, 12))\n",
2110 "assert(cat(enigma.wheel_positions_l) == 'idj')\n",
2111 "assert(enigma.peg_positions == ([8], [22], [12]))\n",
2112 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n",
2113 "\n",
2114 "enigma.advance()\n",
2115 "assert(enigma.wheel_positions == (3, 10, 13))\n",
2116 "assert(cat(enigma.wheel_positions_l) == 'idk')\n",
2117 "assert(enigma.peg_positions == ([8], [22], [11]))\n",
2118 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n",
2119 "\n",
2120 "enigma.advance()\n",
2121 "assert(enigma.wheel_positions == (3, 10, 14))\n",
2122 "assert(cat(enigma.wheel_positions_l) == 'idl')\n",
2123 "assert(enigma.peg_positions == ([8], [22], [10]))\n",
2124 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n",
2125 "\n",
2126 "enigma.advance()\n",
2127 "assert(enigma.wheel_positions == (3, 10, 15))\n",
2128 "assert(cat(enigma.wheel_positions_l) == 'idm')\n",
2129 "assert(enigma.peg_positions == ([8], [22], [9]))\n",
2130 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n",
2131 "\n",
2132 "enigma.advance()\n",
2133 "assert(enigma.wheel_positions == (3, 10, 16))\n",
2134 "assert(cat(enigma.wheel_positions_l) == 'idn')\n",
2135 "assert(enigma.peg_positions == ([8], [22], [8]))\n",
2136 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n",
2137 "\n",
2138 "enigma.advance()\n",
2139 "assert(enigma.wheel_positions == (3, 10, 17))\n",
2140 "assert(cat(enigma.wheel_positions_l) == 'ido')\n",
2141 "assert(enigma.peg_positions == ([8], [22], [7]))\n",
2142 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n",
2143 "\n",
2144 "enigma.advance()\n",
2145 "assert(enigma.wheel_positions == (3, 10, 18))\n",
2146 "assert(cat(enigma.wheel_positions_l) == 'idp')\n",
2147 "assert(enigma.peg_positions == ([8], [22], [6]))\n",
2148 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n",
2149 "\n",
2150 "enigma.advance()\n",
2151 "assert(enigma.wheel_positions == (3, 10, 19))\n",
2152 "assert(cat(enigma.wheel_positions_l) == 'idq')\n",
2153 "assert(enigma.peg_positions == ([8], [22], [5]))\n",
2154 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n",
2155 "\n",
2156 "enigma.advance()\n",
2157 "assert(enigma.wheel_positions == (3, 10, 20))\n",
2158 "assert(cat(enigma.wheel_positions_l) == 'idr')\n",
2159 "assert(enigma.peg_positions == ([8], [22], [4]))\n",
2160 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n",
2161 "\n",
2162 "enigma.advance()\n",
2163 "assert(enigma.wheel_positions == (3, 10, 21))\n",
2164 "assert(cat(enigma.wheel_positions_l) == 'ids')\n",
2165 "assert(enigma.peg_positions == ([8], [22], [3]))\n",
2166 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n",
2167 "\n",
2168 "enigma.advance()\n",
2169 "assert(enigma.wheel_positions == (3, 10, 22))\n",
2170 "assert(cat(enigma.wheel_positions_l) == 'idt')\n",
2171 "assert(enigma.peg_positions == ([8], [22], [2]))\n",
2172 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n",
2173 "\n",
2174 "enigma.advance()\n",
2175 "assert(enigma.wheel_positions == (3, 10, 23))\n",
2176 "assert(cat(enigma.wheel_positions_l) == 'idu')\n",
2177 "assert(enigma.peg_positions == ([8], [22], [1]))\n",
2178 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n",
2179 "\n",
2180 "enigma.advance()\n",
2181 "assert(enigma.wheel_positions == (3, 10, 24))\n",
2182 "assert(cat(enigma.wheel_positions_l) == 'idv')\n",
2183 "assert(enigma.peg_positions == ([8], [22], [0]))\n",
2184 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n",
2185 "\n",
2186 "enigma.advance()\n",
2187 "assert(enigma.wheel_positions == (3, 11, 25))\n",
2188 "assert(cat(enigma.wheel_positions_l) == 'iew')\n",
2189 "assert(enigma.peg_positions == ([8], [21], [25]))\n",
2190 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n",
2191 "\n",
2192 "enigma.advance()\n",
2193 "assert(enigma.wheel_positions == (3, 11, 0))\n",
2194 "assert(cat(enigma.wheel_positions_l) == 'iex')\n",
2195 "assert(enigma.peg_positions == ([8], [21], [24]))\n",
2196 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n",
2197 "\n",
2198 "enigma.advance()\n",
2199 "assert(enigma.wheel_positions == (3, 11, 1))\n",
2200 "assert(cat(enigma.wheel_positions_l) == 'iey')\n",
2201 "assert(enigma.peg_positions == ([8], [21], [23]))\n",
2202 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n",
2203 "\n",
2204 "enigma.advance()\n",
2205 "assert(enigma.wheel_positions == (3, 11, 2))\n",
2206 "assert(cat(enigma.wheel_positions_l) == 'iez')\n",
2207 "assert(enigma.peg_positions == ([8], [21], [22]))\n",
2208 "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'szgyqvclkoihurjwenaxmfptdb')\n",
2209 "\n"
2210 ]
2211 }
2212 ],
2213 "source": [
2214 "enigma.set_wheels('i', 'd', 'z')\n",
2215 "\n",
2216 "for i in range(26):\n",
2217 " enigma.advance()\n",
2218 " print('enigma.advance()')\n",
2219 " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n",
2220 " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n",
2221 " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n",
2222 " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n",
2223 " print()"
2224 ]
2225 },
2226 {
2227 "cell_type": "code",
2228 "execution_count": null,
2229 "metadata": {
2230 "collapsed": true
2231 },
2232 "outputs": [],
2233 "source": []
2234 }
2235 ],
2236 "metadata": {
2237 "kernelspec": {
2238 "display_name": "Python 3",
2239 "language": "python",
2240 "name": "python3"
2241 },
2242 "language_info": {
2243 "codemirror_mode": {
2244 "name": "ipython",
2245 "version": 3
2246 },
2247 "file_extension": ".py",
2248 "mimetype": "text/x-python",
2249 "name": "python",
2250 "nbconvert_exporter": "python",
2251 "pygments_lexer": "ipython3",
2252 "version": "3.4.3+"
2253 }
2254 },
2255 "nbformat": 4,
2256 "nbformat_minor": 0
2257 }