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