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