X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=enigma.py;h=89758f532087985078041473006ce3d6510e3933;hb=6399b876a6d50d11ad318ab0fd0db74e03168ed8;hp=1150763d35eabc8be0e4fa5cf1c4f5cc3ed26b6f;hpb=027a37ff0a8b8e5dd28c8f6ce3819315d1b7a284;p=cipher-tools.git diff --git a/enigma.py b/enigma.py index 1150763..89758f5 100644 --- a/enigma.py +++ b/enigma.py @@ -1,7 +1,9 @@ # coding: utf-8 +################################## # # Enigma machine +################################## # Specification from [Codes and Ciphers](http://www.codesandciphers.org.uk/enigma/rotorspec.htm) page. # # Example Enigma machines from [Louise Dale](http://enigma.louisedade.co.uk/enigma.html) (full simulation) and [EnigmaCo](http://enigmaco.de/enigma/enigma.html) (good animation of the wheels, but no ring settings). @@ -12,6 +14,23 @@ import string import collections +import multiprocessing +import itertools +import logging + +logger = logging.getLogger('engima') +logger.setLevel(logging.WARNING) +# logger.setLevel(logging.INFO) +# logger.setLevel(logging.DEBUG) + +# create the logging file handler +fh = logging.FileHandler("enigma.log") +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +fh.setFormatter(formatter) + +# add handler to logger object +logger.addHandler(fh) + # Some convenience functions @@ -41,14 +60,14 @@ wheel_viii_spec = 'fkqhtlxocbjspdzramewniuygv' beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos' gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd' -wheel_i_pegs = ['q'] -wheel_ii_pegs = ['e'] -wheel_iii_pegs = ['v'] -wheel_iv_pegs = ['j'] -wheel_v_pegs = ['z'] -wheel_vi_pegs = ['z', 'm'] -wheel_vii_pegs = ['z', 'm'] -wheel_viii_pegs = ['z', 'm'] +wheel_i_notches = ['q'] +wheel_ii_notches = ['e'] +wheel_iii_notches = ['v'] +wheel_iv_notches = ['j'] +wheel_v_notches = ['z'] +wheel_vi_notches = ['z', 'm'] +wheel_vii_notches = ['z', 'm'] +wheel_viii_notches = ['z', 'm'] reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw' reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su' @@ -59,24 +78,6 @@ class LetterTransformer(object): """A generic substitution cipher, that has different transforms in the forward and backward directions. It requires that the transforms for all letters by provided. - - >>> lt = LetterTransformer([('z', 'a')] + [(l, string.ascii_lowercase[i+1]) \ - for i, l in enumerate(string.ascii_lowercase[:-1])], \ - raw_transform = True) - >>> lt.forward_map - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0] - >>> lt.backward_map - [25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] - - >>> lt = LetterTransformer(cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase))) - >>> lt.forward_map - [25, 24, 23, 22, 2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21] - >>> lt.backward_map - [5, 6, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 3, 2, 1, 0] - >>> cat(lt.forward(l) for l in string.ascii_lowercase) - 'zyxwcabdefghijklmnopqrstuv' - >>> cat(lt.backward(l) for l in string.ascii_lowercase) - 'fgehijklmnopqrstuvwxyzdcba' """ def __init__(self, specification, raw_transform=False): if raw_transform: @@ -132,16 +133,6 @@ class Plugboard(LetterTransformer): """A plugboard, a type of letter transformer where forward and backward transforms are the same. If a letter isn't explicitly transformed, it is kept as it is. - - >>> pb = Plugboard('ua pf rq so ni ey bg hl tx zj'.upper()) - >>> pb.forward_map - [20, 6, 2, 3, 24, 15, 1, 11, 13, 25, 10, 7, 12, 8, 18, 5, 17, 16, 14, 23, 0, 21, 22, 19, 4, 9] - >>> pb.forward_map == pb.backward_map - True - >>> cat(pb.forward(l) for l in string.ascii_lowercase) - 'ugcdypblnzkhmisfrqoxavwtej' - >>> cat(pb.backward(l) for l in string.ascii_lowercase) - 'ugcdypblnzkhmisfrqoxavwtej' """ def parse_specification(self, specification): return [tuple(clean(p)) for p in specification.split()] @@ -166,16 +157,6 @@ class Plugboard(LetterTransformer): class Reflector(Plugboard): """A reflector is a plugboard that requires 13 transforms. - - >>> reflector_b = Reflector(reflector_b_spec) - >>> reflector_b.forward_map == reflector_b.backward_map - True - >>> reflector_b.forward_map - [24, 17, 20, 7, 16, 18, 11, 3, 15, 23, 13, 6, 14, 10, 12, 8, 4, 1, 5, 25, 2, 22, 21, 9, 0, 19] - >>> cat(reflector_b.forward(l) for l in string.ascii_lowercase) - 'yruhqsldpxngokmiebfzcwvjat' - >>> cat(reflector_b.backward(l) for l in string.ascii_lowercase) - 'yruhqsldpxngokmiebfzcwvjat' """ def validate_transform(self, transform): if len(transform) != 13: @@ -204,52 +185,6 @@ class SimpleWheel(LetterTransformer): Letter inputs and outputs are given relative to the frame holding the wheel, so if the wheel is advanced three places, an input of 'p' will enter the wheel on the position under the wheel's 'q' label. - - >>> rotor_1_transform = list(zip(string.ascii_lowercase, 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower())) - >>> wheel_1 = SimpleWheel(rotor_1_transform, raw_transform=True) - >>> cat(wheel_1.forward(l) for l in string.ascii_lowercase) - 'ekmflgdqvzntowyhxuspaibrcj' - >>> cat(wheel_1.backward(l) for l in string.ascii_lowercase) - 'uwygadfpvzbeckmthxslrinqoj' - - - >>> wheel_2 = SimpleWheel(wheel_ii_spec) - >>> cat(wheel_2.forward(l) for l in string.ascii_lowercase) - 'ajdksiruxblhwtmcqgznpyfvoe' - >>> cat(wheel_2.backward(l) for l in string.ascii_lowercase) - 'ajpczwrlfbdkotyuqgenhxmivs' - - >>> wheel_3 = SimpleWheel(wheel_iii_spec) - >>> wheel_3.set_position('a') - >>> wheel_3.advance() - >>> cat(wheel_3.forward(l) for l in string.ascii_lowercase) - 'cegikboqswuymxdhvfzjltrpna' - >>> cat(wheel_3.backward(l) for l in string.ascii_lowercase) - 'zfaobrcpdteumygxhwivkqjnls' - >>> wheel_3.position - 1 - >>> wheel_3.position_l - 'b' - - >>> for _ in range(24): wheel_3.advance() - >>> wheel_3.position - 25 - >>> wheel_3.position_l - 'z' - >>> cat(wheel_3.forward(l) for l in string.ascii_lowercase) - 'pcegikmdqsuywaozfjxhblnvtr' - >>> cat(wheel_3.backward(l) for l in string.ascii_lowercase) - 'nubhcqdterfvgwoaizjykxmslp' - - >>> wheel_3.advance() - >>> wheel_3.position - 0 - >>> wheel_3.position_l - 'a' - >>> cat(wheel_3.forward(l) for l in string.ascii_lowercase) - 'bdfhjlcprtxvznyeiwgakmusqo' - >>> cat(wheel_3.backward(l) for l in string.ascii_lowercase) - 'tagbpcsdqeufvnzhyixjwlrkom' """ def __init__(self, transform, position='a', raw_transform=False): super(SimpleWheel, self).__init__(transform, raw_transform) @@ -262,7 +197,11 @@ class SimpleWheel(LetterTransformer): return object.__getattribute__(self, name) def set_position(self, position): - self.position = ord(position) - ord('a') + if isinstance(position, str): + # self.position = ord(position) - ord('a') + self.position = pos(position) + else: + self.position = position def forward(self, letter): if letter in string.ascii_lowercase: @@ -278,14 +217,13 @@ class SimpleWheel(LetterTransformer): def advance(self): self.position = (self.position + 1) % 26 - # return self.position class Wheel(SimpleWheel): """A wheel with a movable ring. - The ring holds the letters and the pegs that turn other wheels. The core + The ring holds the letters and the notches that turn other wheels. The core holds the wiring that does the transformation. The ring position is how many steps the core is turned relative to the ring. @@ -298,125 +236,12 @@ class Wheel(SimpleWheel): The position_l is the position of the ring, or what would be observed by the user of the Enigma machine. - The peg_positions are the number of advances of this wheel before it will + The notch_positions are the number of advances of this wheel before it will advance the next wheel. - >>> wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1) - >>> wheel_3.position - 1 - >>> wheel_3.peg_positions - [20] - >>> wheel_3.position_l - 'b' - >>> wheel_3.advance() - >>> wheel_3.position - 2 - >>> wheel_3.peg_positions - [19] - >>> wheel_3.position_l - 'c' - - >>> wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3) - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'xkqhwpvngzrcfoiaselbtymjdu' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'ptlyrmidoxbswhnfckquzgeavj' - >>> wheel_6.position - 25 - >>> 11 in wheel_6.peg_positions - True - >>> 24 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'b' - - >>> wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'jpgvoumfyqbenhzrdkasxlictw' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'skxqlhcnwarvgmebjptyfdzuio' - >>> wheel_6.position - 0 - >>> 10 in wheel_6.peg_positions - True - >>> 23 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'c' - - >>> for _ in range(22): wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'mgxantkzsyqjcufirldvhoewbp' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'dymswobuplgraevzkqifntxcjh' - >>> wheel_6.position - 22 - >>> 1 in wheel_6.peg_positions - True - >>> 14 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'y' - - >>> wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'fwzmsjyrxpibtehqkcugndvaol' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'xlrvnatokfqzduyjphemswbigc' - >>> wheel_6.position - 23 - >>> 0 in wheel_6.peg_positions - True - >>> 13 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'z' - - >>> wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'vylrixqwohasdgpjbtfmcuznke' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'kqumzsnjepyctxiogdlrvahfbw' - >>> wheel_6.position - 24 - >>> 25 in wheel_6.peg_positions - True - >>> 12 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'a' - - >>> wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'xkqhwpvngzrcfoiaselbtymjdu' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'ptlyrmidoxbswhnfckquzgeavj' - >>> wheel_6.position - 25 - >>> 24 in wheel_6.peg_positions - True - >>> 11 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'b' - - >>> wheel_6.advance() - >>> cat(wheel_6.forward(l) for l in string.ascii_lowercase) - 'jpgvoumfyqbenhzrdkasxlictw' - >>> cat(wheel_6.backward(l) for l in string.ascii_lowercase) - 'skxqlhcnwarvgmebjptyfdzuio' - >>> wheel_6.position - 0 - >>> 23 in wheel_6.peg_positions - True - >>> 10 in wheel_6.peg_positions - True - >>> wheel_6.position_l - 'c' - """ - def __init__(self, transform, ring_peg_letters, ring_setting=1, position='a', raw_transform=False): - self.ring_peg_letters = ring_peg_letters + def __init__(self, transform, ring_notch_letters, ring_setting=1, position='a', raw_transform=False): + self.ring_notch_letters = ring_notch_letters self.ring_setting = ring_setting super(Wheel, self).__init__(transform, position=position, raw_transform=raw_transform) self.set_position(position) @@ -428,516 +253,35 @@ class Wheel(SimpleWheel): return object.__getattribute__(self, name) def set_position(self, position): - self.position = (pos(position) - self.ring_setting + 1) % 26 - # self.position_l = position - self.peg_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_peg_letters] + if isinstance(position, str): + self.position = (pos(position) - self.ring_setting + 1) % 26 + else: + self.position = (position - self.ring_setting) % 26 + # # self.notch_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_notch_letters] + # self.notch_positions = [(pos(p) - (self.position + self.ring_setting - 1)) % 26 for p in self.ring_notch_letters] + self.notch_positions = [(self.position + self.ring_setting - 1 - pos(p)) % 26 for p in self.ring_notch_letters] def advance(self): super(Wheel, self).advance() - self.peg_positions = [(p - 1) % 26 for p in self.peg_positions] - # self.position_l = unpos(self.position + self.ring_setting - 1) - # return self.position - - + self.notch_positions = [(p + 1) % 26 for p in self.notch_positions] + return self.position class Enigma(object): """An Enigma machine. - >>> enigma = Enigma(reflector_b_spec, \ - wheel_i_spec, wheel_i_pegs, \ - wheel_ii_spec, wheel_ii_pegs, \ - wheel_iii_spec, wheel_iii_pegs, \ - 1, 1, 1, \ - '') - >>> enigma.set_wheels('a', 'a', 't') - >>> enigma.wheel_positions - (0, 0, 19) - >>> cat(enigma.wheel_positions_l) - 'aat' - >>> enigma.peg_positions - ([16], [4], [2]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'puvioztjdhxmlyeawsrgbcqknf' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 0, 20) - >>> cat(enigma.wheel_positions_l) - 'aau' - >>> enigma.peg_positions - ([16], [4], [1]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'baigpldqcowfyzjehvtsxrkumn' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 0, 21) - >>> cat(enigma.wheel_positions_l) - 'aav' - >>> enigma.peg_positions - ([16], [4], [0]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'mnvfydiwgzsoablrxpkutchqej' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 1, 22) - >>> cat(enigma.wheel_positions_l) - 'abw' - >>> enigma.peg_positions - ([16], [3], [25]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'ulfopcykswhbzvderqixanjtgm' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 1, 23) - >>> cat(enigma.wheel_positions_l) - 'abx' - >>> enigma.peg_positions - ([16], [3], [24]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'qmwftdyovursbzhxaklejicpgn' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 1, 24) - >>> cat(enigma.wheel_positions_l) - 'aby' - >>> enigma.peg_positions - ([16], [3], [23]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'oljmzxrvucybdqasngpwihtfke' - - - - - >>> enigma.set_wheels('a', 'd', 't') - >>> enigma.wheel_positions - (0, 3, 19) - >>> cat(enigma.wheel_positions_l) - 'adt' - >>> enigma.peg_positions - ([16], [1], [2]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'zcbpqxwsjiuonmldethrkygfva' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 3, 20) - >>> cat(enigma.wheel_positions_l) - 'adu' - >>> enigma.peg_positions - ([16], [1], [1]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'ehprawjbngotxikcsdqlzyfmvu' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 3, 21) - >>> cat(enigma.wheel_positions_l) - 'adv' - >>> enigma.peg_positions - ([16], [1], [0]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'eqzxarpihmnvjkwgbfuyslodtc' - - >>> enigma.advance() - >>> enigma.wheel_positions - (0, 4, 22) - >>> cat(enigma.wheel_positions_l) - 'aew' - >>> enigma.peg_positions - ([16], [0], [25]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'qedcbtpluzmhkongavwfirsyxj' - - >>> enigma.advance() - >>> enigma.wheel_positions - (1, 5, 23) - >>> cat(enigma.wheel_positions_l) - 'bfx' - >>> enigma.peg_positions - ([15], [25], [24]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'iwuedhsfazqxytvrkpgncoblmj' - - >>> enigma.advance() - >>> enigma.wheel_positions - (1, 5, 24) - >>> cat(enigma.wheel_positions_l) - 'bfy' - >>> enigma.peg_positions - ([15], [25], [23]) - >>> cat(enigma.lookup(l) for l in string.ascii_lowercase) - 'baknstqzrmcxjdvygiefwoulph' - - - >>> enigma.set_wheels('a', 'a', 'a') - >>> ct = enigma.encipher('testmessage') - >>> ct - 'olpfhnvflyn' - - >>> enigma.set_wheels('a', 'd', 't') - >>> ct = enigma.encipher('testmessage') - >>> ct - 'lawnjgpwjik' - - - >>> enigma.set_wheels('b', 'd', 'q') - >>> ct = enigma.encipher('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') - >>> ct - 'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr' - >>> enigma.left_wheel.position_l - 'c' - >>> enigma.middle_wheel.position_l - 'h' - >>> enigma.right_wheel.position_l - 'a' - - # Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm - # Enigma simulation settings are - # http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJEU;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX - >>> enigma31 = Enigma(reflector_b_spec, \ - wheel_i_spec, wheel_i_pegs, \ - wheel_v_spec, wheel_v_pegs, \ - wheel_iii_spec, wheel_iii_pegs, \ - 6, 20, 24, \ - 'ua pf rq so ni ey bg hl tx zj') - - >>> enigma31.set_wheels('j', 'e', 'u') - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (4, 11, 24) - >>> cat(enigma31.wheel_positions_l) - 'jev' - >>> enigma31.peg_positions - ([7], [21], [0]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'mvqjlyowkdieasgzcunxrbhtfp' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (4, 12, 25) - >>> cat(enigma31.wheel_positions_l) - 'jfw' - >>> enigma31.peg_positions - ([7], [20], [25]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'sjolzuyvrbwdpxcmtiaqfhknge' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (4, 12, 0) - >>> cat(enigma31.wheel_positions_l) - 'jfx' - >>> enigma31.peg_positions - ([7], [20], [24]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'qrxedkoywufmlvgsabpzjnicht' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (4, 12, 1) - >>> cat(enigma31.wheel_positions_l) - 'jfy' - >>> enigma31.peg_positions - ([7], [20], [23]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'hpsukliagqefwvtbjxcodnmrzy' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (4, 12, 2) - >>> cat(enigma31.wheel_positions_l) - 'jfz' - >>> enigma31.peg_positions - ([7], [20], [22]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'zevnbpyqowrtxdifhkulscjmga' - - - >>> enigma31.set_wheels('i', 'd', 'z') - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 3) - >>> cat(enigma31.wheel_positions_l) - 'ida' - >>> enigma31.peg_positions - ([8], [22], [21]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'ikhpqrvcambzjondefwyxgsutl' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 4) - >>> cat(enigma31.wheel_positions_l) - 'idb' - >>> enigma31.peg_positions - ([8], [22], [20]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'cdabskhgzwfmlqvunyexpojtri' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 5) - >>> cat(enigma31.wheel_positions_l) - 'idc' - >>> enigma31.peg_positions - ([8], [22], [19]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'pcbwiqhgemyvjsuaftnroldzkx' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 6) - >>> cat(enigma31.wheel_positions_l) - 'idd' - >>> enigma31.peg_positions - ([8], [22], [18]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'xcbfvdnouptmlghjzwykierasq' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 7) - >>> cat(enigma31.wheel_positions_l) - 'ide' - >>> enigma31.peg_positions - ([8], [22], [17]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'xfvglbdynuseriwqpmkzjcoaht' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 8) - >>> cat(enigma31.wheel_positions_l) - 'idf' - >>> enigma31.peg_positions - ([8], [22], [16]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'tfpqlbouynsewjgcdxkahzmriv' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 9) - >>> cat(enigma31.wheel_positions_l) - 'idg' - >>> enigma31.peg_positions - ([8], [22], [15]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'cjaunvlwtbygzexrspqidfhokm' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 10) - >>> cat(enigma31.wheel_positions_l) - 'idh' - >>> enigma31.peg_positions - ([8], [22], [14]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'yltxkrqvowebzpingfucshjdam' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 11) - >>> cat(enigma31.wheel_positions_l) - 'idi' - >>> enigma31.peg_positions - ([8], [22], [13]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'myktluzrnxceaiqsohpdfwvjbg' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 12) - >>> cat(enigma31.wheel_positions_l) - 'idj' - >>> enigma31.peg_positions - ([8], [22], [12]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'pynjrmiugdqxfcvakewzhoslbt' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 13) - >>> cat(enigma31.wheel_positions_l) - 'idk' - >>> enigma31.peg_positions - ([8], [22], [11]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'mwvedyplnoxhaijgrqtszcbkfu' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 14) - >>> cat(enigma31.wheel_positions_l) - 'idl' - >>> enigma31.peg_positions - ([8], [22], [10]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'qcbrfeutvoxpnmjladzhgiykws' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 15) - >>> cat(enigma31.wheel_positions_l) - 'idm' - >>> enigma31.peg_positions - ([8], [22], [9]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'dnoahryetsmukbcvwfjilpqzgx' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 16) - >>> cat(enigma31.wheel_positions_l) - 'idn' - >>> enigma31.peg_positions - ([8], [22], [8]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'nidcfehgbqsovalyjzkxwmutpr' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 17) - >>> cat(enigma31.wheel_positions_l) - 'ido' - >>> enigma31.peg_positions - ([8], [22], [7]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'joifxdulcarhzpbntkwqgysevm' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 18) - >>> cat(enigma31.wheel_positions_l) - 'idp' - >>> enigma31.peg_positions - ([8], [22], [6]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'ptnlsxvozmwdjchayuebrgkfqi' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 19) - >>> cat(enigma31.wheel_positions_l) - 'idq' - >>> enigma31.peg_positions - ([8], [22], [5]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'slwopzqnmxybihdeguavrtcjkf' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 20) - >>> cat(enigma31.wheel_positions_l) - 'idr' - >>> enigma31.peg_positions - ([8], [22], [4]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'hcbedwlamzogixkytsrqvufnpj' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 21) - >>> cat(enigma31.wheel_positions_l) - 'ids' - >>> enigma31.peg_positions - ([8], [22], [3]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'odxbjwzrmelkisavuhnyqpfctg' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 22) - >>> cat(enigma31.wheel_positions_l) - 'idt' - >>> enigma31.peg_positions - ([8], [22], [2]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'udgbfeclrwnhxksvtioqapjmzy' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 23) - >>> cat(enigma31.wheel_positions_l) - 'idu' - >>> enigma31.peg_positions - ([8], [22], [1]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'nrdczqxmowvshaiufblypkjgte' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 10, 24) - >>> cat(enigma31.wheel_positions_l) - 'idv' - >>> enigma31.peg_positions - ([8], [22], [0]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'hkifjdoacebqtzgulyvmpsxwrn' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 11, 25) - >>> cat(enigma31.wheel_positions_l) - 'iew' - >>> enigma31.peg_positions - ([8], [21], [25]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'yptzuhofqvnmlkgbixwcejsrad' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 11, 0) - >>> cat(enigma31.wheel_positions_l) - 'iex' - >>> enigma31.peg_positions - ([8], [21], [24]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'vkdcwhqfjibzsptngumoraeyxl' - - >>> enigma31.advance() - >>> enigma31.wheel_positions - (3, 11, 1) - >>> cat(enigma31.wheel_positions_l) - 'iey' - >>> enigma31.peg_positions - ([8], [21], [23]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'wenpbqrouxlkychdfgzvitajms' - - - >>> enigma31.set_wheels('i', 'd', 'z') - >>> enigma31.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure') - 'gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz' - >>> enigma31.wheel_positions - (3, 12, 6) - >>> cat(enigma31.wheel_positions_l) - 'ifd' - >>> enigma31.peg_positions - ([8], [20], [18]) - >>> cat(enigma31.lookup(l) for l in string.ascii_lowercase) - 'urygzpdmxtwshqvfnbljaokice' - - >>> enigma31.set_wheels('i', 'd', 'z') - >>> enigma31.decipher('gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz') - 'verylongtestmessagewithanextrabitofmessageforgoodmeasure' + """ def __init__(self, reflector_spec, - left_wheel_spec, left_wheel_pegs, - middle_wheel_spec, middle_wheel_pegs, - right_wheel_spec, right_wheel_pegs, + left_wheel_spec, left_wheel_notches, + middle_wheel_spec, middle_wheel_notches, + right_wheel_spec, right_wheel_notches, left_ring_setting, middle_ring_setting, right_ring_setting, plugboard_setting): self.reflector = Reflector(reflector_spec) - self.left_wheel = Wheel(left_wheel_spec, left_wheel_pegs, ring_setting=left_ring_setting) - self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_pegs, ring_setting=middle_ring_setting) - self.right_wheel = Wheel(right_wheel_spec, right_wheel_pegs, ring_setting=right_ring_setting) + self.left_wheel = Wheel(left_wheel_spec, left_wheel_notches, ring_setting=left_ring_setting) + self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_notches, ring_setting=middle_ring_setting) + self.right_wheel = Wheel(right_wheel_spec, right_wheel_notches, ring_setting=right_ring_setting) self.plugboard = Plugboard(plugboard_setting) def __getattribute__(self,name): @@ -945,8 +289,8 @@ class Enigma(object): return self.left_wheel.position, self.middle_wheel.position, self.right_wheel.position elif name=='wheel_positions_l': return self.left_wheel.position_l, self.middle_wheel.position_l, self.right_wheel.position_l - elif name=='peg_positions': - return self.left_wheel.peg_positions, self.middle_wheel.peg_positions, self.right_wheel.peg_positions + elif name=='notch_positions': + return self.left_wheel.notch_positions, self.middle_wheel.notch_positions, self.right_wheel.notch_positions else: return object.__getattribute__(self, name) @@ -970,9 +314,9 @@ class Enigma(object): def advance(self): advance_middle = False advance_left = False - if 0 in self.right_wheel.peg_positions: + if 0 in self.right_wheel.notch_positions: advance_middle = True - if 0 in self.middle_wheel.peg_positions: + if 0 in self.middle_wheel.notch_positions: advance_left = True advance_middle = True self.right_wheel.advance() @@ -997,7 +341,7 @@ class Enigma(object): # print('enigma.advance()') # print("assert(enigma.wheel_positions == {})".format(enigma.wheel_positions)) # print("assert(cat(enigma.wheel_positions_l) == '{}')".format(cat(enigma.wheel_positions_l))) -# print("assert(enigma.peg_positions == {})".format(enigma.peg_positions)) +# print("assert(enigma.notch_positions == {})".format(enigma.notch_positions)) # print("assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')".format(cat(enigma.lookup(l) for l in string.ascii_lowercase))) # print()