1def plugboard(to_convert, list_of_letter_pairs):
2 """Convert a given string using sets of two letters. Each letter converts to its neighbor."""
3 converted = ''
4 for ch in to_convert:
5 # create a list of all sets that contain the current letter
6 corresponding_set = [letters_set for letters_set in list_of_letter_pairs if ch in letters_set]
7
8 # if the list is empty or the current character
9 # isn't a letter, then the character will not be changed
10 if not corresponding_set or not ch.isalpha():
11 converted += ch
12 else:
13 # get difference between the set {'ch', 'other_letter'} and {ch} to find 'other_letter'
14 # (next() and iter() are used to extract the single member of the set)
15 converted += next(iter(corresponding_set[0] - {ch}))
16 return converted
17
18
19def rotor(to_convert, dict_letters):
20 converted = ''
21 for ch in to_convert:
22 if not ch.isalpha(): # only convert letters
23 converted += ch
24 continue
25 converted += dict_letters[ch]
26 return converted
27
28
29def enigma_encrypt(plugboard_position=[], rotor_position={}):
30 def decorator(func):
31 def inner(to_encrypt):
32 after_plugboard = plugboard(to_encrypt, plugboard_position)
33 after_rotor = rotor(after_plugboard, rotor_position)
34 func(after_rotor)
35 return inner
36 return decorator
37
38
39def enigma_decrypt(plugboard_position=[], rotor_position={}):
40 def decorator(func):
41 def inner(to_decrypt):
42 rotor_reversed = {v: k for k, v in rotor_position.items()}
43 after_rotor = rotor(to_decrypt, rotor_reversed)
44 after_plugboard = plugboard(after_rotor, plugboard_position)
45 func(after_plugboard)
46 return inner
47 return decorator
F.FF.....
======================================================================
FAIL: test_full_letter_set (test.TestCombination)
Test decrypting an encrypted text against itself.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 139, in test_full_letter_set
self.assertEqual(combined('i love python'), 'i love python')
AssertionError: None != 'i love python'
======================================================================
FAIL: test_full_letter_set (test.TestDecryptor)
Test the decryptor function with all letters in the rotor.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 112, in test_full_letter_set
self.assertEqual(decrypted('mlx fuver cbakn jad guoyq aixb mlx pzhw sat'),
AssertionError: None != 'the quick brown fox jumps over the lazy dog'
======================================================================
FAIL: test_full_letter_set (test.TestEncryptor)
Test the encryptor function with all letters in the rotor.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 89, in test_full_letter_set
self.assertEqual(encrypted('the quick brown fox jumps over the lazy dog'),
AssertionError: None != 'mjg cavsk nrqfy zqd haulp qxgr mjg itob eqw'
----------------------------------------------------------------------
Ran 9 tests in 0.001s
FAILED (failures=3)
f | 1 | def plugboard(to_convert, list_of_letter_pairs): | f | 1 | def plugboard(to_convert, list_of_letter_pairs): |
n | 2 | """ Convert a given string using sets of two letters. Each letter converts to its neighbor.""" | n | 2 | """Convert a given string using sets of two letters. Each letter converts to its neighbor.""" |
3 | |||||
4 | converted = '' | 3 | converted = '' | ||
n | 5 | for i in range(len(to_convert)): | n | 4 | for ch in to_convert: |
6 | # create a list of all sets that contain the current letter | 5 | # create a list of all sets that contain the current letter | ||
n | 7 | corresponding_set = [letters_set for letters_set in list_of_letter_pairs if to_convert[i] in letters_set] | n | 6 | corresponding_set = [letters_set for letters_set in list_of_letter_pairs if ch in letters_set] |
8 | 7 | ||||
9 | # if the list is empty or the current character | 8 | # if the list is empty or the current character | ||
10 | # isn't a letter, then the character will not be changed | 9 | # isn't a letter, then the character will not be changed | ||
n | 11 | if not corresponding_set or not to_convert[i].isalpha(): | n | 10 | if not corresponding_set or not ch.isalpha(): |
12 | converted += to_convert[i] | 11 | converted += ch | ||
13 | |||||
14 | else: | 12 | else: | ||
n | 15 | # the list should contain a single set | n | 13 | # get difference between the set {'ch', 'other_letter'} and {ch} to find 'other_letter' |
16 | corresponding_set = corresponding_set[0] | 14 | # (next() and iter() are used to extract the single member of the set) | ||
17 | for letter in corresponding_set: | 15 | converted += next(iter(corresponding_set[0] - {ch})) | ||
18 | # find the other letter and add it to the result | ||||
19 | if letter != to_convert[i]: | ||||
20 | converted += letter | ||||
21 | break | ||||
22 | return converted | 16 | return converted | ||
23 | 17 | ||||
24 | 18 | ||||
25 | def rotor(to_convert, dict_letters): | 19 | def rotor(to_convert, dict_letters): | ||
26 | converted = '' | 20 | converted = '' | ||
n | 27 | for i in range(len(to_convert)): | n | 21 | for ch in to_convert: |
28 | if not to_convert.isalpha(): # only convert letters | 22 | if not ch.isalpha(): # only convert letters | ||
29 | converted += to_convert[i] | 23 | converted += ch | ||
30 | continue | 24 | continue | ||
n | 31 | converted += dict_letters[to_convert[i]] | n | 25 | converted += dict_letters[ch] |
32 | return converted | 26 | return converted | ||
33 | 27 | ||||
34 | 28 | ||||
35 | def enigma_encrypt(plugboard_position=[], rotor_position={}): | 29 | def enigma_encrypt(plugboard_position=[], rotor_position={}): | ||
36 | def decorator(func): | 30 | def decorator(func): | ||
37 | def inner(to_encrypt): | 31 | def inner(to_encrypt): | ||
38 | after_plugboard = plugboard(to_encrypt, plugboard_position) | 32 | after_plugboard = plugboard(to_encrypt, plugboard_position) | ||
39 | after_rotor = rotor(after_plugboard, rotor_position) | 33 | after_rotor = rotor(after_plugboard, rotor_position) | ||
40 | func(after_rotor) | 34 | func(after_rotor) | ||
n | 41 | n | |||
42 | return inner | 35 | return inner | ||
n | 43 | n | |||
44 | return decorator | 36 | return decorator | ||
45 | 37 | ||||
46 | 38 | ||||
47 | def enigma_decrypt(plugboard_position=[], rotor_position={}): | 39 | def enigma_decrypt(plugboard_position=[], rotor_position={}): | ||
48 | def decorator(func): | 40 | def decorator(func): | ||
49 | def inner(to_decrypt): | 41 | def inner(to_decrypt): | ||
50 | rotor_reversed = {v: k for k, v in rotor_position.items()} | 42 | rotor_reversed = {v: k for k, v in rotor_position.items()} | ||
51 | after_rotor = rotor(to_decrypt, rotor_reversed) | 43 | after_rotor = rotor(to_decrypt, rotor_reversed) | ||
52 | after_plugboard = plugboard(after_rotor, plugboard_position) | 44 | after_plugboard = plugboard(after_rotor, plugboard_position) | ||
53 | func(after_plugboard) | 45 | func(after_plugboard) | ||
n | 54 | n | |||
55 | return inner | 46 | return inner | ||
t | 56 | t | |||
57 | return decorator | 47 | return decorator |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|