Worked on Enigma, mainly changing how the notch positions are handled
[cipher-training.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_notches, position='b',
161 ring_setting=1)
162 self.assertEqual(wheel.position, 1)
163 self.assertEqual(wheel.notch_positions, [6])
164 self.assertEqual(wheel.position_l, 'b')
165
166 wheel.advance()
167 self.assertEqual(wheel.position, 2)
168 self.assertEqual(wheel.notch_positions, [7])
169 self.assertEqual(wheel.position_l, 'c')
170
171 def test_init2(self):
172 wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b',
173 ring_setting=3)
174 self.assertEqual(wheel.position, 25)
175 self.assertIn(2, wheel.notch_positions)
176 self.assertIn(15, wheel.notch_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_notches, position='b',
187 ring_setting=3)
188 wheel.advance()
189
190 self.assertEqual(wheel.position, 0)
191 self.assertIn(3, wheel.notch_positions)
192 self.assertIn(16, wheel.notch_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_notches, position='b',
203 ring_setting=3)
204 for _ in range(23):
205 wheel.advance()
206
207 self.assertEqual(wheel.position, 22)
208 self.assertIn(12, wheel.notch_positions)
209 self.assertIn(25, wheel.notch_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_notches, 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.notch_positions)
226 self.assertIn(13, wheel.notch_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_notches, position='b',
237 ring_setting=3)
238 for _ in range(25):
239 wheel.advance()
240
241 self.assertEqual(wheel.position, 24)
242 self.assertIn(1, wheel.notch_positions)
243 self.assertIn(14, wheel.notch_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_notches, position='b',
254 ring_setting=3)
255 for _ in range(26):
256 wheel.advance()
257
258 self.assertEqual(wheel.position, 25)
259 self.assertIn(2, wheel.notch_positions)
260 self.assertIn(15, wheel.notch_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_notches, position='b',
271 ring_setting=3)
272 for _ in range(27):
273 wheel.advance()
274
275 self.assertEqual(wheel.position, 0)
276 self.assertIn(3, wheel.notch_positions)
277 self.assertIn(16, wheel.notch_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_notches, 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.notch_positions, [5])
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.notch_positions, [4])
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.notch_positions, [4])
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.notch_positions, [5])
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.notch_positions, [10])
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.notch_positions, [10])
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.notch_positions, [11])
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.notch_positions, [16])
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.notch_positions, [17])
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_notches,
339 wheel_ii_spec, wheel_ii_notches,
340 wheel_iii_spec, wheel_iii_notches,
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_notches,
349 wheel_v_spec, wheel_v_notches,
350 wheel_iii_spec, wheel_iii_notches,
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_notches,
357 wheel_iii_spec, wheel_iii_notches,
358 wheel_ii_spec, wheel_ii_notches,
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.notch_positions, ([10], [22], [24]))
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.notch_positions, ([10], [22], [25]))
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.notch_positions, ([10], [22], [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.notch_positions, ([10], [23], [1]))
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.notch_positions, ([10], [23], [2]))
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.notch_positions, ([10], [23], [3]))
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.notch_positions, ([10], [25], [24]))
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.notch_positions, ([10], [25], [25]))
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.notch_positions, ([10], [25], [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.notch_positions, ([10], [0], [1]))
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.notch_positions, ([11], [1], [2]))
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.notch_positions, ([11], [1], [3]))
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.notch_positions, ([19], [5], [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.notch_positions, ([19], [6], [1]))
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.notch_positions, ([19], [6], [2]))
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.notch_positions, ([19], [6], [3]))
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.notch_positions, ([19], [6], [4]))
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.notch_positions, ([18], [4], [5]))
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.notch_positions, ([18], [4], [6]))
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.notch_positions, ([18], [4], [7]))
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.notch_positions, ([18], [4], [8]))
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.notch_positions, ([18], [4], [9]))
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.notch_positions, ([18], [4], [10]))
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.notch_positions, ([18], [4], [11]))
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.notch_positions, ([18], [4], [12]))
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.notch_positions, ([18], [4], [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.notch_positions, ([18], [4], [14]))
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.notch_positions, ([18], [4], [15]))
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.notch_positions, ([18], [4], [16]))
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.notch_positions, ([18], [4], [17]))
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.notch_positions, ([18], [4], [18]))
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.notch_positions, ([18], [4], [19]))
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.notch_positions, ([18], [4], [20]))
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.notch_positions, ([18], [4], [21]))
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.notch_positions, ([18], [4], [22]))
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.notch_positions, ([18], [4], [23]))
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.notch_positions, ([18], [4], [24]))
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.notch_positions, ([18], [4], [25]))
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.notch_positions, ([18], [4], [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.notch_positions, ([18], [5], [1]))
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.notch_positions, ([18], [5], [2]))
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.notch_positions, ([18], [5], [3]))
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.notch_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.notch_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.notch_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.notch_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.notch_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.notch_positions, ([15], [25], [23]))
714
715 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 22))
716 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayt')
717 self.assertEqual(self.enigma31.notch_positions, ([10], [25], [24]))
718 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'izhrgtecaslkywvqpdjfxonumb')
719
720 self.enigma31.advance()
721 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 23))
722 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayu')
723 self.assertEqual(self.enigma31.notch_positions, ([10], [25], [25]))
724 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dtoavihgflwjnmcsrqpbzekyxu')
725
726 self.enigma31.advance()
727 self.assertEqual(self.enigma31.wheel_positions, (21, 5, 24))
728 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayv')
729 self.assertEqual(self.enigma31.notch_positions, ([10], [25], [0]))
730 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xquhtpsdwkjonmlfbvgecriazy')
731
732 self.enigma31.advance()
733 self.assertEqual(self.enigma31.wheel_positions, (21, 6, 25))
734 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azw')
735 self.assertEqual(self.enigma31.notch_positions, ([10], [0], [1]))
736 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dofapcluvmngjkbezyxwhitsrq')
737
738 self.enigma31.advance()
739 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 0))
740 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bax')
741 self.assertEqual(self.enigma31.notch_positions, ([11], [1], [2]))
742 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'jdlbmswztapcexrkuofiqygnvh')
743
744 self.enigma31.advance()
745 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 1))
746 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bay')
747 self.assertEqual(self.enigma31.notch_positions, ([11], [1], [3]))
748 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'iydcnuhgawsoxelztvkqfrjmbp')
749
750
751 self.enigma31.set_wheels('a', 'z', 't')
752 # self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22))
753 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt')
754 # self.assertEqual(self.enigma31.notch_positions, ([16], [0], [2]))
755
756 # self.enigma31.advance()
757 # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23))
758 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau')
759 # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [1]))
760
761 # self.enigma31.advance()
762 # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24))
763 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav')
764 # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [0]))
765
766 # self.enigma31.advance()
767 # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25))
768 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw')
769 # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [25]))
770
771 # self.enigma31.advance()
772 # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0))
773 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx')
774 # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [24]))
775
776 # self.enigma31.advance()
777 # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1))
778 # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby')
779 # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [23]))
780
781 self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22))
782 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt')
783 self.assertEqual(self.enigma31.notch_positions, ([10], [0], [24]))
784 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'idjbptqwacsvnmregokfzlhyxu')
785
786 self.enigma31.advance()
787 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23))
788 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau')
789 self.assertEqual(self.enigma31.notch_positions, ([11], [1], [25]))
790 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'rniszouwcxtvqbfymadkglhjpe')
791
792 self.enigma31.advance()
793 self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24))
794 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav')
795 self.assertEqual(self.enigma31.notch_positions, ([11], [1], [0]))
796 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'qijfsdmkbchugxtwazeolypnvr')
797
798 self.enigma31.advance()
799 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25))
800 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw')
801 self.assertEqual(self.enigma31.notch_positions, ([11], [2], [1]))
802 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xprtlozyskjewqfbncidvumahg')
803
804 self.enigma31.advance()
805 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0))
806 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx')
807 self.assertEqual(self.enigma31.notch_positions, ([11], [2], [2]))
808 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'vtfuyczoqxmpkwhlisrbdanjeg')
809
810 self.enigma31.advance()
811 self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1))
812 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby')
813 self.assertEqual(self.enigma31.notch_positions, ([11], [2], [3]))
814 assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'tjrhzpqdobwxyuifgcvansklme')
815
816
817 def test_encipher_with_ring(self):
818
819 self.enigma31.set_wheels('i', 'z', 'd')
820 ct = self.enigma31.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')
821 self.assertEqual(ct,
822 'apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')
823 self.assertEqual(self.enigma31.wheel_positions, (4, 9, 10))
824 self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jch')
825 self.assertEqual(self.enigma31.notch_positions, ([19], [3], [12]))
826 self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase),
827 'mopnigfuesqwadbcktjrhylzvx')
828
829 self.enigma31.set_wheels('i', 'z', 'd')
830 pt = self.enigma31.decipher('apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')
831 self.assertEqual(pt,
832 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')
833
834 if __name__ == '__main__':
835 unittest.main()