# 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).
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
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'
"""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:
"""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()]
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:
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)
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:
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.
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)
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):
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)
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()
# 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()