Added logging, removed additional implementation of bombe from engima.py
[cipher-tools.git] / test_enigma.py
1 import unittest
2 import collections
3 import string
4
5 from enigma import *
6
7 class LetterTransformerTest(unittest.TestCase):
8
9 def test_maps1(self):
10 lt = LetterTransformer([('z', 'a')] + \
11 list(zip(string.ascii_lowercase, string.ascii_lowercase[1:])),
12 raw_transform = True)
13 self.assertEqual(lt.forward_map,
14 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0])
16 self.assertEqual(lt.backward_map,
17 [25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
18 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
19
20
21 def test_maps2(self):
22 lt = LetterTransformer(cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase)))
23 self.assertEqual(lt.forward_map,
24 [25, 24, 23, 22, 2, 0, 1, 3, 4, 5, 6, 7, 8, 9,
25 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
26 self.assertEqual(lt.backward_map,
27 [5, 6, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
28 17, 18, 19, 20, 21, 22, 23, 24, 25, 3, 2, 1, 0])
29
30 def test_transform(self):
31 lt = LetterTransformer(cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase)))
32 self.assertEqual(cat(lt.forward(l) for l in string.ascii_lowercase),
33 'zyxwcabdefghijklmnopqrstuv')
34 self.assertEqual(cat(lt.backward(l) for l in string.ascii_lowercase),
35 'fgehijklmnopqrstuvwxyzdcba')
36
37
38 class PlugboardTest(unittest.TestCase):
39 def setUp(self):
40 self.pb = Plugboard('ua pf rq so ni ey bg hl tx zj'.upper())
41
42 def test_maps(self):
43 self.assertEqual(self.pb.forward_map,
44 [20, 6, 2, 3, 24, 15, 1, 11, 13, 25, 10, 7, 12,
45 8, 18, 5, 17, 16, 14, 23, 0, 21, 22, 19, 4, 9])
46 self.assertEqual(self.pb.forward_map, self.pb.backward_map)
47
48 def test_transform(self):
49 self.assertEqual(cat(self.pb.forward(l)
50 for l in string.ascii_lowercase),
51 'ugcdypblnzkhmisfrqoxavwtej')
52 self.assertEqual(cat(self.pb.backward(l)
53 for l in string.ascii_lowercase),
54 'ugcdypblnzkhmisfrqoxavwtej')
55
56
57 class ReflectorTest(unittest.TestCase):
58 def setUp(self):
59 self.ref = Reflector(reflector_b_spec)
60
61 def test_maps(self):
62 self.assertEqual(self.ref.forward_map,
63 [24, 17, 20, 7, 16, 18, 11, 3, 15, 23, 13, 6, 14,
64 10, 12, 8, 4, 1, 5, 25, 2, 22, 21, 9, 0, 19])
65 self.assertEqual(self.ref.forward_map, self.ref.backward_map)
66
67 def test_transform(self):
68 self.assertEqual(cat(self.ref.forward(l)
69 for l in string.ascii_lowercase),
70 'yruhqsldpxngokmiebfzcwvjat')
71 self.assertEqual(cat(self.ref.backward(l)
72 for l in string.ascii_lowercase),
73 'yruhqsldpxngokmiebfzcwvjat')
74
75
76 class SimpleWheelTest(unittest.TestCase):
77 def test_init1(self):
78 rotor_1_transform = list(zip(string.ascii_lowercase,
79 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower()))
80 wheel_1 = SimpleWheel(rotor_1_transform, raw_transform=True)
81 self.assertEqual(cat(wheel_1.forward(l)
82 for l in string.ascii_lowercase),
83 'ekmflgdqvzntowyhxuspaibrcj')
84 self.assertEqual(cat(wheel_1.backward(l)
85 for l in string.ascii_lowercase),
86 'uwygadfpvzbeckmthxslrinqoj')
87
88 def test_init2(self):
89 wheel_2 = SimpleWheel(wheel_ii_spec)
90 self.assertEqual(cat(wheel_2.forward(l)
91 for l in string.ascii_lowercase),
92 'ajdksiruxblhwtmcqgznpyfvoe')
93 self.assertEqual(cat(wheel_2.backward(l)
94 for l in string.ascii_lowercase),
95 'ajpczwrlfbdkotyuqgenhxmivs')
96
97 def test_set_position(self):
98 wheel_3 = SimpleWheel(wheel_iii_spec)
99 wheel_3.set_position('a')
100 self.assertEqual(wheel_3.position, 0)
101 self.assertEqual(wheel_3.position_l, 'a')
102
103 wheel_3.set_position('f')
104 self.assertEqual(wheel_3.position, 5)
105 self.assertEqual(wheel_3.position_l, 'f')
106
107 wheel_3.advance()
108 self.assertEqual(wheel_3.position, 6)
109 self.assertEqual(wheel_3.position_l, 'g')
110
111 wheel_3.set_position(12)
112 self.assertEqual(wheel_3.position, 12)
113 self.assertEqual(wheel_3.position_l, 'm')
114
115 wheel_3.advance()
116 self.assertEqual(wheel_3.position, 13)
117 self.assertEqual(wheel_3.position_l, 'n')
118
119
120 def test_advance(self):
121 wheel_3 = SimpleWheel(wheel_iii_spec)
122 wheel_3.set_position('a')
123 wheel_3.advance()
124 self.assertEqual(cat(wheel_3.forward(l)
125 for l in string.ascii_lowercase),
126 'cegikboqswuymxdhvfzjltrpna')
127 self.assertEqual(cat(wheel_3.backward(l)
128 for l in string.ascii_lowercase),
129 'zfaobrcpdteumygxhwivkqjnls')
130 self.assertEqual(wheel_3.position, 1)
131 self.assertEqual(wheel_3.position_l, 'b')
132
133 for _ in range(24): wheel_3.advance()
134
135 self.assertEqual(wheel_3.position, 25)
136 self.assertEqual(wheel_3.position_l, 'z')
137
138 self.assertEqual(cat(wheel_3.forward(l)
139 for l in string.ascii_lowercase),
140 'pcegikmdqsuywaozfjxhblnvtr')
141 self.assertEqual(cat(wheel_3.backward(l)
142 for l in string.ascii_lowercase),
143 'nubhcqdterfvgwoaizjykxmslp')
144
145 wheel_3.advance()
146 self.assertEqual(wheel_3.position, 0)
147 self.assertEqual(wheel_3.position_l, 'a')
148
149
150 self.assertEqual(cat(wheel_3.forward(l)
151 for l in string.ascii_lowercase),
152 'bdfhjlcprtxvznyeiwgakmusqo')
153 self.assertEqual(cat(wheel_3.backward(l)
154 for l in string.ascii_lowercase),
155 'tagbpcsdqeufvnzhyixjwlrkom')
156
157
158 class WheelTest(unittest.TestCase):
159 def test_init1(self):
160 wheel = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b',
161 ring_setting=1)
162 self.assertEqual(wheel.position, 1)
163 self.assertEqual(wheel.peg_positions, [20])
164 self.assertEqual(wheel.position_l, 'b')
165
166 wheel.advance()
167 self.assertEqual(wheel.position, 2)
168 self.assertEqual(wheel.peg_positions, [19])
169 self.assertEqual(wheel.position_l, 'c')
170
171 def test_init2(self):
172 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
173 ring_setting=3)
174 self.assertEqual(wheel.position, 25)
175 self.assertIn(11, wheel.peg_positions)
176 self.assertIn(24, wheel.peg_positions)
177 self.assertEqual(wheel.position_l, 'b')
178 self.assertEqual(cat(wheel.forward(l)
179 for l in string.ascii_lowercase),
180 'xkqhwpvngzrcfoiaselbtymjdu')
181 self.assertEqual(cat(wheel.backward(l)
182 for l in string.ascii_lowercase),
183 'ptlyrmidoxbswhnfckquzgeavj')
184
185 def test_advance(self):
186 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
187 ring_setting=3)
188 wheel.advance()
189
190 self.assertEqual(wheel.position, 0)
191 self.assertIn(10, wheel.peg_positions)
192 self.assertIn(23, wheel.peg_positions)
193 self.assertEqual(wheel.position_l, 'c')
194 self.assertEqual(cat(wheel.forward(l)
195 for l in string.ascii_lowercase),
196 'jpgvoumfyqbenhzrdkasxlictw')
197 self.assertEqual(cat(wheel.backward(l)
198 for l in string.ascii_lowercase),
199 'skxqlhcnwarvgmebjptyfdzuio')
200
201 def test_advance_23(self):
202 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
203 ring_setting=3)
204 for _ in range(23):
205 wheel.advance()
206
207 self.assertEqual(wheel.position, 22)
208 self.assertIn(1, wheel.peg_positions)
209 self.assertIn(14, wheel.peg_positions)
210 self.assertEqual(wheel.position_l, 'y')
211 self.assertEqual(cat(wheel.forward(l)
212 for l in string.ascii_lowercase),
213 'mgxantkzsyqjcufirldvhoewbp')
214 self.assertEqual(cat(wheel.backward(l)
215 for l in string.ascii_lowercase),
216 'dymswobuplgraevzkqifntxcjh')
217
218 def test_advance_24(self):
219 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
220 ring_setting=3)
221 for _ in range(24):
222 wheel.advance()
223
224 self.assertEqual(wheel.position, 23)
225 self.assertIn(0, wheel.peg_positions)
226 self.assertIn(13, wheel.peg_positions)
227 self.assertEqual(wheel.position_l, 'z')
228 self.assertEqual(cat(wheel.forward(l)
229 for l in string.ascii_lowercase),
230 'fwzmsjyrxpibtehqkcugndvaol')
231 self.assertEqual(cat(wheel.backward(l)
232 for l in string.ascii_lowercase),
233 'xlrvnatokfqzduyjphemswbigc')
234
235 def test_advance_25(self):
236 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
237 ring_setting=3)
238 for _ in range(25):
239 wheel.advance()
240
241 self.assertEqual(wheel.position, 24)
242 self.assertIn(25, wheel.peg_positions)
243 self.assertIn(12, wheel.peg_positions)
244 self.assertEqual(wheel.position_l, 'a')
245 self.assertEqual(cat(wheel.forward(l)
246 for l in string.ascii_lowercase),
247 'vylrixqwohasdgpjbtfmcuznke')
248 self.assertEqual(cat(wheel.backward(l)
249 for l in string.ascii_lowercase),
250 'kqumzsnjepyctxiogdlrvahfbw')
251
252 def test_advance_26(self):
253 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
254 ring_setting=3)
255 for _ in range(26):
256 wheel.advance()
257
258 self.assertEqual(wheel.position, 25)
259 self.assertIn(24, wheel.peg_positions)
260 self.assertIn(11, wheel.peg_positions)
261 self.assertEqual(wheel.position_l, 'b')
262 self.assertEqual(cat(wheel.forward(l)
263 for l in string.ascii_lowercase),
264 'xkqhwpvngzrcfoiaselbtymjdu')
265 self.assertEqual(cat(wheel.backward(l)
266 for l in string.ascii_lowercase),
267 'ptlyrmidoxbswhnfckquzgeavj')
268
269 def test_advance_27(self):
270 wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b',
271 ring_setting=3)
272 for _ in range(27):
273 wheel.advance()
274
275 self.assertEqual(wheel.position, 0)
276 self.assertIn(23, wheel.peg_positions)
277 self.assertIn(10, wheel.peg_positions)
278 self.assertEqual(wheel.position_l, 'c')
279 self.assertEqual(cat(wheel.forward(l)
280 for l in string.ascii_lowercase),
281 'jpgvoumfyqbenhzrdkasxlictw')
282 self.assertEqual(cat(wheel.backward(l)
283 for l in string.ascii_lowercase),
284 'skxqlhcnwarvgmebjptyfdzuio')
285
286 def test_set_position(self):
287 wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, ring_setting=3)
288 wheel_3.set_position('a')
289 self.assertEqual(wheel_3.position, 24)
290 self.assertEqual(wheel_3.position_l, 'a')
291 self.assertEqual(wheel_3.peg_positions, [21])
292
293 wheel_3.set_position('z')
294 self.assertEqual(wheel_3.position, 23)
295 self.assertEqual(wheel_3.position_l, 'z')
296 self.assertEqual(wheel_3.peg_positions, [22])
297
298 wheel_3.set_position(26)
299 self.assertEqual(wheel_3.position, 23)
300 self.assertEqual(wheel_3.position_l, 'z')
301 self.assertEqual(wheel_3.peg_positions, [22])
302
303 wheel_3.set_position(27)
304 self.assertEqual(wheel_3.position, 24)
305 self.assertEqual(wheel_3.position_l, 'a')
306 self.assertEqual(wheel_3.peg_positions, [21])
307
308 wheel_3.set_position('f')
309 self.assertEqual(wheel_3.position, 3)
310 self.assertEqual(wheel_3.position_l, 'f')
311 self.assertEqual(wheel_3.peg_positions, [16])
312
313 wheel_3.set_position(6)
314 self.assertEqual(wheel_3.position, 3)
315 self.assertEqual(wheel_3.position_l, 'f')
316 self.assertEqual(wheel_3.peg_positions, [16])
317
318 wheel_3.advance()
319 self.assertEqual(wheel_3.position, 4)
320 self.assertEqual(wheel_3.position_l, 'g')
321 self.assertEqual(wheel_3.peg_positions, [15])
322
323 wheel_3.set_position(12)
324 self.assertEqual(wheel_3.position, 9)
325 self.assertEqual(wheel_3.position_l, 'l')
326 self.assertEqual(wheel_3.peg_positions, [10])
327
328 wheel_3.advance()
329 self.assertEqual(wheel_3.position, 10)
330 self.assertEqual(wheel_3.position_l, 'm')
331 self.assertEqual(wheel_3.peg_positions, [9])
332
333
334 class EnigmaTest(unittest.TestCase):
335
336 def setUp(self):
337 self.enigma = Enigma(reflector_b_spec,
338 wheel_i_spec, wheel_i_pegs,
339 wheel_ii_spec, wheel_ii_pegs,
340 wheel_iii_spec, wheel_iii_pegs,
341 1, 1, 1,
342 '')
343
344 # Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm
345 # Enigma simulation settings are
346 # http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJEU;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX
347 self.enigma31 = Enigma(reflector_b_spec,
348 wheel_i_spec, wheel_i_pegs,
349 wheel_v_spec, wheel_v_pegs,
350 wheel_iii_spec, wheel_iii_pegs,
351 6, 20, 24,
352 'ua pf rq so ni ey bg hl tx zj')
353
354 # Settings for Bletchley Park outreach department's Enigma
355 self.enigma_bp = Enigma(reflector_b_spec,
356 wheel_i_spec, wheel_i_pegs,
357 wheel_iii_spec, wheel_iii_pegs,
358 wheel_ii_spec, wheel_ii_pegs,
359 1, 26, 26,
360 'qm we ro tu zj ps dl fg')
361
362
363 def test_middle_advance(self):
364 self.enigma.set_wheels('a', 'a', 't')
365 self.assertEqual(self.enigma.wheel_positions, (0, 0, 19))
366 self.assertEqual(cat(self.enigma.wheel_positions_l), 'aat')
367 self.assertEqual(self.enigma.peg_positions, ([16], [4], [2]))
368 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
369 'puvioztjdhxmlyeawsrgbcqknf')
370
371 self.enigma.advance()
372 self.assertEqual(self.enigma.wheel_positions, (0, 0, 20))
373 self.assertEqual(cat(self.enigma.wheel_positions_l), 'aau')
374 self.assertEqual(self.enigma.peg_positions, ([16], [4], [1]))
375 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
376 'baigpldqcowfyzjehvtsxrkumn')
377
378 self.enigma.advance()
379 self.assertEqual(self.enigma.wheel_positions, (0, 0, 21))
380 self.assertEqual(cat(self.enigma.wheel_positions_l), 'aav')
381 self.assertEqual(self.enigma.peg_positions, ([16], [4], [0]))
382 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
383 'mnvfydiwgzsoablrxpkutchqej')
384
385 self.enigma.advance()
386 self.assertEqual(self.enigma.wheel_positions, (0, 1, 22))
387 self.assertEqual(cat(self.enigma.wheel_positions_l), 'abw')
388 self.assertEqual(self.enigma.peg_positions, ([16], [3], [25]))
389 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
390 'ulfopcykswhbzvderqixanjtgm')
391
392 self.enigma.advance()
393 self.assertEqual(self.enigma.wheel_positions, (0, 1, 23))
394 self.assertEqual(cat(self.enigma.wheel_positions_l), 'abx')
395 self.assertEqual(self.enigma.peg_positions, ([16], [3], [24]))
396 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
397 'qmwftdyovursbzhxaklejicpgn')
398
399 self.enigma.advance()
400 self.assertEqual(self.enigma.wheel_positions, (0, 1, 24))
401 self.assertEqual(cat(self.enigma.wheel_positions_l), 'aby')
402 self.assertEqual(self.enigma.peg_positions, ([16], [3], [23]))
403 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
404 'oljmzxrvucybdqasngpwihtfke')
405
406
407 def test_double_advance(self):
408 self.enigma.set_wheels('a', 'd', 't')
409 self.assertEqual(self.enigma.wheel_positions, (0, 3, 19))
410 self.assertEqual(cat(self.enigma.wheel_positions_l), 'adt')
411 self.assertEqual(self.enigma.peg_positions, ([16], [1], [2]))
412 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
413 'zcbpqxwsjiuonmldethrkygfva')
414
415 self.enigma.advance()
416 self.assertEqual(self.enigma.wheel_positions, (0, 3, 20))
417 self.assertEqual(cat(self.enigma.wheel_positions_l), 'adu')
418 self.assertEqual(self.enigma.peg_positions, ([16], [1], [1]))
419 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
420 'ehprawjbngotxikcsdqlzyfmvu')
421
422 self.enigma.advance()
423 self.assertEqual(self.enigma.wheel_positions, (0, 3, 21))
424 self.assertEqual(cat(self.enigma.wheel_positions_l), 'adv')
425 self.assertEqual(self.enigma.peg_positions, ([16], [1], [0]))
426 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
427 'eqzxarpihmnvjkwgbfuyslodtc')
428
429 self.enigma.advance()
430 self.assertEqual(self.enigma.wheel_positions, (0, 4, 22))
431 self.assertEqual(cat(self.enigma.wheel_positions_l), 'aew')
432 self.assertEqual(self.enigma.peg_positions, ([16], [0], [25]))
433 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
434 'qedcbtpluzmhkongavwfirsyxj')
435
436 self.enigma.advance()
437 self.assertEqual(self.enigma.wheel_positions, (1, 5, 23))
438 self.assertEqual(cat(self.enigma.wheel_positions_l), 'bfx')
439 self.assertEqual(self.enigma.peg_positions, ([15], [25], [24]))
440 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
441 'iwuedhsfazqxytvrkpgncoblmj')
442
443 self.enigma.advance()
444 self.assertEqual(self.enigma.wheel_positions, (1, 5, 24))
445 self.assertEqual(cat(self.enigma.wheel_positions_l), 'bfy')
446 self.assertEqual(self.enigma.peg_positions, ([15], [25], [23]))
447 self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase),
448 'baknstqzrmcxjdvygiefwoulph')
449
450
451 def test_simple_encipher(self):
452 self.enigma.set_wheels('a', 'a', 'a')
453 ct = self.enigma.encipher('testmessage')
454 self.assertEqual(ct, 'olpfhnvflyn')
455
456 self.enigma.set_wheels('a', 'd', 't')
457 ct = self.enigma.encipher('testmessage')
458 self.assertEqual(ct, 'lawnjgpwjik')
459
460 self.enigma.set_wheels('b', 'd', 'q')
461 ct = self.enigma.encipher('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
462 self.assertEqual(ct,
463 'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr')
464 self.assertEqual(cat(self.enigma.wheel_positions_l), 'cha')
465
466
467 def test_advance_with_ring_settings(self):
468 self.enigma31.set_wheels('j', 'e', 'u')
469
470 self.enigma31.advance()
471 self.assertEqual(self.enigma31.wheel_positions, (4, 11, 24))
472 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jev')
473 self.assertEqual(self.enigma31.peg_positions, ([7], [21], [0]))
474 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
475 'mvqjlyowkdieasgzcunxrbhtfp')
476
477 self.enigma31.advance()
478 self.assertEqual(self.enigma31.wheel_positions, (4, 12, 25))
479 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfw')
480 self.assertEqual(self.enigma31.peg_positions, ([7], [20], [25]))
481 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
482 'sjolzuyvrbwdpxcmtiaqfhknge')
483
484 self.enigma31.advance()
485 self.assertEqual(self.enigma31.wheel_positions, (4, 12, 0))
486 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfx')
487 self.assertEqual(self.enigma31.peg_positions, ([7], [20], [24]))
488 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
489 'qrxedkoywufmlvgsabpzjnicht')
490
491 self.enigma31.advance()
492 self.assertEqual(self.enigma31.wheel_positions, (4, 12, 1))
493 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfy')
494 self.assertEqual(self.enigma31.peg_positions, ([7], [20], [23]))
495 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
496 'hpsukliagqefwvtbjxcodnmrzy')
497
498 self.enigma31.advance()
499 self.assertEqual(self.enigma31.wheel_positions, (4, 12, 2))
500 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfz')
501 self.assertEqual(self.enigma31.peg_positions, ([7], [20], [22]))
502 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
503 'zevnbpyqowrtxdifhkulscjmga')
504
505
506 def test_advance_with_ring_settings_2(self):
507 self.enigma31.set_wheels('i', 'd', 'z')
508
509 self.enigma31.advance()
510 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 3))
511 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ida')
512 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [21]))
513 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
514 'ikhpqrvcambzjondefwyxgsutl')
515
516 self.enigma31.advance()
517 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 4))
518 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idb')
519 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [20]))
520 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
521 'cdabskhgzwfmlqvunyexpojtri')
522
523 self.enigma31.advance()
524 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 5))
525 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idc')
526 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [19]))
527 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
528 'pcbwiqhgemyvjsuaftnroldzkx')
529
530 self.enigma31.advance()
531 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 6))
532 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idd')
533 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [18]))
534 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
535 'xcbfvdnouptmlghjzwykierasq')
536
537 self.enigma31.advance()
538 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 7))
539 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ide')
540 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [17]))
541 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
542 'xfvglbdynuseriwqpmkzjcoaht')
543
544 self.enigma31.advance()
545 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 8))
546 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idf')
547 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [16]))
548 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
549 'tfpqlbouynsewjgcdxkahzmriv')
550
551 self.enigma31.advance()
552 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 9))
553 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idg')
554 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [15]))
555 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
556 'cjaunvlwtbygzexrspqidfhokm')
557
558 self.enigma31.advance()
559 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 10))
560 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idh')
561 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [14]))
562 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
563 'yltxkrqvowebzpingfucshjdam')
564
565 self.enigma31.advance()
566 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 11))
567 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idi')
568 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [13]))
569 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
570 'myktluzrnxceaiqsohpdfwvjbg')
571
572 self.enigma31.advance()
573 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 12))
574 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idj')
575 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [12]))
576 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
577 'pynjrmiugdqxfcvakewzhoslbt')
578
579 self.enigma31.advance()
580 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 13))
581 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idk')
582 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [11]))
583 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
584 'mwvedyplnoxhaijgrqtszcbkfu')
585
586 self.enigma31.advance()
587 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 14))
588 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idl')
589 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [10]))
590 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
591 'qcbrfeutvoxpnmjladzhgiykws')
592
593 self.enigma31.advance()
594 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 15))
595 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idm')
596 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [9]))
597 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
598 'dnoahryetsmukbcvwfjilpqzgx')
599
600 self.enigma31.advance()
601 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 16))
602 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idn')
603 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [8]))
604 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
605 'nidcfehgbqsovalyjzkxwmutpr')
606
607 self.enigma31.advance()
608 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 17))
609 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ido')
610 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [7]))
611 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
612 'joifxdulcarhzpbntkwqgysevm')
613
614 self.enigma31.advance()
615 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 18))
616 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idp')
617 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [6]))
618 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
619 'ptnlsxvozmwdjchayuebrgkfqi')
620
621 self.enigma31.advance()
622 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 19))
623 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idq')
624 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [5]))
625 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
626 'slwopzqnmxybihdeguavrtcjkf')
627
628 self.enigma31.advance()
629 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 20))
630 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idr')
631 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [4]))
632 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
633 'hcbedwlamzogixkytsrqvufnpj')
634
635 self.enigma31.advance()
636 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 21))
637 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ids')
638 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [3]))
639 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
640 'odxbjwzrmelkisavuhnyqpfctg')
641
642 self.enigma31.advance()
643 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 22))
644 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idt')
645 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [2]))
646 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
647 'udgbfeclrwnhxksvtioqapjmzy')
648
649 self.enigma31.advance()
650 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 23))
651 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idu')
652 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [1]))
653 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
654 'nrdczqxmowvshaiufblypkjgte')
655
656 self.enigma31.advance()
657 self.assertEqual(self.enigma31.wheel_positions, (3, 10, 24))
658 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idv')
659 self.assertEqual(self.enigma31.peg_positions, ([8], [22], [0]))
660 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
661 'hkifjdoacebqtzgulyvmpsxwrn')
662
663 self.enigma31.advance()
664 self.assertEqual(self.enigma31.wheel_positions, (3, 11, 25))
665 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iew')
666 self.assertEqual(self.enigma31.peg_positions, ([8], [21], [25]))
667 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
668 'yptzuhofqvnmlkgbixwcejsrad')
669
670 self.enigma31.advance()
671 self.assertEqual(self.enigma31.wheel_positions, (3, 11, 0))
672 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iex')
673 self.assertEqual(self.enigma31.peg_positions, ([8], [21], [24]))
674 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
675 'vkdcwhqfjibzsptngumoraeyxl')
676
677 self.enigma31.advance()
678 self.assertEqual(self.enigma31.wheel_positions, (3, 11, 1))
679 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iey')
680 self.assertEqual(self.enigma31.peg_positions, ([8], [21], [23]))
681 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
682 'wenpbqrouxlkychdfgzvitajms')
683
684 def test_double_advance_with_ring_settings_2(self):
685 self.enigma31.set_wheels('a', 'y', 't')
686 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 22))
687 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayt')
688 self.assertEqual(self.enigma31.peg_positions, ([16], [1], [2]))
689
690 self.enigma31.advance()
691 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 23))
692 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayu')
693 self.assertEqual(self.enigma31.peg_positions, ([16], [1], [1]))
694
695 self.enigma31.advance()
696 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 24))
697 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayv')
698 self.assertEqual(self.enigma31.peg_positions, ([16], [1], [0]))
699
700 self.enigma31.advance()
701 self.assertEqual(self.enigma31.wheel_positions, (21, 6, 25))
702 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azw')
703 self.assertEqual(self.enigma31.peg_positions, ([16], [0], [25]))
704
705 self.enigma31.advance()
706 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 0))
707 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bax')
708 self.assertEqual(self.enigma31.peg_positions, ([15], [25], [24]))
709
710 self.enigma31.advance()
711 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 1))
712 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bay')
713 self.assertEqual(self.enigma31.peg_positions, ([15], [25], [23]))
714
715 self.enigma31.set_wheels('a', 'z', 't')
716 self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22))
717 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt')
718 self.assertEqual(self.enigma31.peg_positions, ([16], [0], [2]))
719
720 self.enigma31.advance()
721 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23))
722 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau')
723 self.assertEqual(self.enigma31.peg_positions, ([15], [25], [1]))
724
725 self.enigma31.advance()
726 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24))
727 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav')
728 self.assertEqual(self.enigma31.peg_positions, ([15], [25], [0]))
729
730 self.enigma31.advance()
731 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25))
732 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw')
733 self.assertEqual(self.enigma31.peg_positions, ([15], [24], [25]))
734
735 self.enigma31.advance()
736 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0))
737 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx')
738 self.assertEqual(self.enigma31.peg_positions, ([15], [24], [24]))
739
740 self.enigma31.advance()
741 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1))
742 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby')
743 self.assertEqual(self.enigma31.peg_positions, ([15], [24], [23]))
744
745
746 def test_encipher_with_ring(self):
747
748 self.enigma31.set_wheels('i', 'z', 'd')
749 ct = self.enigma31.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')
750 self.assertEqual(ct,
751 'apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')
752 self.assertEqual(self.enigma31.wheel_positions, (4, 9, 10))
753 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jch')
754 self.assertEqual(self.enigma31.peg_positions, ([7], [23], [14]))
755 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
756 'mopnigfuesqwadbcktjrhylzvx')
757
758 self.enigma31.set_wheels('i', 'z', 'd')
759 pt = self.enigma31.decipher('apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')
760 self.assertEqual(pt,
761 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')
762
763 if __name__ == '__main__':
764 unittest.main()