Commits

Cédric Bonhomme committed e120a81 Merge

Merged branch cedric in default.

  • Participants
  • Parent commits b0eedcd, 8a5a2a4

Comments (0)

Files changed (4)

+pyEnigma
+========
+
+#### Python Enigma cypher machine simulator.
+
+Presentation
+------------
+Python 2 -> Python 3
+
+Usage
+-----
+
+    $ echo "Hello World" | ./cypher_enigma_safe.py secret B  I II V 
+    Vjpfw Ekdxj
+
+    $ echo "Vjpfw Ekdxj" | ./cypher_enigma_safe.py secret B  I II V
+    Hello World
+
+License
+-------
+
+Author
+------
+* [Christophe Goessen](https://bitbucket.org/azmaeve) (main author)
+* [Cédric Bonhomme](http://cedricbonhomme.org/)

File cypher_enigma_safe.py

+#! /usr/bin/env python
+#-*- coding: utf-8 -*-
+
 from rotor import *
 from enigma import *
 import sys
-"""
- A trivial and minimaliste CLI
+
+"""A trivial and minimaliste CLI.
 """
 
+def usage():
+    print("Usage:")
+    print('\techo "Hello World" | ./cypher_enigma_safe.py key ref rotor1 rotor2 rotor3')
+    print("\nExample:")
+    print('\t$ echo "Hello World" | ./cypher_enigma_safe.py secret B  I II IV')
+    print("\tXtrmk Sfjyu")
+
 if __name__ == "__main__":
-    key = sys.argv[1]
-    ref = sys.argv[2]
-    r1 = sys.argv[3]
-    r2 = sys.argv[4]
-    r3 = sys.argv[5]
-    plugs_s = sys.argv[6]
+    # Point of entry in execution mode
+    try:
+        key = sys.argv[1]
+        ref = sys.argv[2]
+        r1 = sys.argv[3]
+        r2 = sys.argv[4]
+        r3 = sys.argv[5]
+    except:
+        usage()
+        exit()
     raw = sys.stdin.read(-1)
     seq = raw.upper()
-    
+
     ct = 0
     a = None
     b = None
             b = c.upper()
             ct =0
             plugs.append((a,b))
-            
-    rotors = {"I":ROTOR_I,"II":ROTOR_II,"III":ROTOR_III,"IV":ROTOR_IV,"V":ROTOR_V,"VI":ROTOR_VI,"VII":ROTOR_VII}
-    reflectors = {"A":ROTOR_Reflector_A,"B":ROTOR_Reflector_B,"C":ROTOR_Reflector_C}
-    
-    engr = Enigma(reflectors[ref], rotors[r1], rotors[r2], rotors[r3],key,plugs)
+
+    rotors = { \
+          "I":ROTOR_I,"II":ROTOR_II,"III":ROTOR_III,"IV":ROTOR_IV, \
+          "V":ROTOR_V,"VI":ROTOR_VI,"VII":ROTOR_VII \
+          }
+    reflectors = { \
+          "A":ROTOR_Reflector_A,"B":ROTOR_Reflector_B, \
+          "C":ROTOR_Reflector_C \
+          }
+
+    engr = Enigma(reflectors[ref], rotors[r1], rotors[r2], \
+            rotors[r3], key, plugs)
     res = engr.encipher(seq)
-    i = 0
     fres = ""
-    while i < len(res):
-        if raw[i].islower():
-            fres += res[i].lower()
+    for idx, char in enumerate(res):
+        if raw[idx].islower():
+            fres += char.lower()
         else:
-            fres += res[i]
-        
-        i += 1
-    print fres
+            fres += char
+    print(fres)
+#! /usr/bin/env python
+#-*- coding: utf-8 -*-
+
 from rotor import *
-from string import maketrans
 
-class Enigma:
-  def __init__(self,ref,r3,r2,r1,setting='AAA',plugs = [],ringset=1):
-    self.reflector = ref
-    self.rotor1 = r1
-    self.rotor2 = r2
-    self.rotor3 = r3
-    
-    self.rotor1.state = setting[0]
-    self.rotor2.state = setting[1]
-    self.rotor3.state = setting[2]
-    self.reflector.state = 'A'
-    self.ringset = ringset
-    
-    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    alpha_out = [" "]*26
-    for i in range(len(alpha)):
-        alpha_out[i] = alpha[i]
-    for k,v in plugs:
-        alpha_out[ord(k)-ord('A')] = v
-        alpha_out[ord(v)-ord('A')] = k
-    
-    self.transtab = maketrans(alpha,"".join(alpha_out))
-    
-  def encipher(self,plaintext_in):
-    ciphertext = ''
-    plaintext = plaintext_in.translate(self.transtab)
-    for c in plaintext:
+class Enigma(object):
+    def __init__(self, ref, r3, r2, r1, setting='AAA', plugs = [], ringset=1):
+        self.reflector = ref
+        self.rotor1 = r1
+        self.rotor2 = r2
+        self.rotor3 = r3
 
-      if self.rotor2.is_in_turnover_pos():
-        self.rotor2.notch()
-        self.rotor3.notch()
-      if self.rotor1.is_in_turnover_pos():
-        self.rotor2.notch()
-      
-      self.rotor1.notch()
-      
+        self.rotor1.state = setting[0]
+        self.rotor2.state = setting[1]
+        self.rotor3.state = setting[2]
+        self.reflector.state = 'A'
+        self.ringset = ringset
 
-      if not c.isalpha():
-          ciphertext += c
-          continue
-      t = self.rotor1.encipher_right(c)
-      t = self.rotor2.encipher_right(t)
-      t = self.rotor3.encipher_right(t)
-      t = self.reflector.encipher(t)
-      t = self.rotor3.encipher_left(t)
-      t = self.rotor2.encipher_left(t)
-      t = self.rotor1.encipher_left(t)
-      ciphertext += t
-    return ciphertext.translate(self.transtab)
+        alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        alpha_out = [" "] * 26
+        for i in range(len(alpha)):
+            alpha_out[i] = alpha[i]
+        for k,v in plugs:
+            alpha_out[ord(k)-ord('A')] = v
+            alpha_out[ord(v)-ord('A')] = k
+
+        try:
+            self.transtab = str.maketrans(alpha, "".join(alpha_out))
+        except:
+            # Python 2
+            from string import maketrans
+            self.transtab = maketrans(alpha,"".join(alpha_out))
+
+    def encipher(self, plaintext_in):
+        ciphertext = ''
+        plaintext = plaintext_in.translate(self.transtab)
+        for c in plaintext:
+            if self.rotor2.is_in_turnover_pos():
+                self.rotor2.notch()
+                self.rotor3.notch()
+            if self.rotor1.is_in_turnover_pos():
+                self.rotor2.notch()
+
+            self.rotor1.notch()
+
+            if not c.isalpha():
+                ciphertext += c
+                continue
+            t = self.rotor1.encipher_right(c)
+            t = self.rotor2.encipher_right(t)
+            t = self.rotor3.encipher_right(t)
+            t = self.reflector.encipher(t)
+            t = self.rotor3.encipher_left(t)
+            t = self.rotor2.encipher_left(t)
+            t = self.rotor1.encipher_left(t)
+            ciphertext += t
+        return ciphertext.translate(self.transtab)
-import sys
+#! /usr/bin/env python
+#-*- coding: utf-8 -*-
 
-class Reflector:
-  def __init__(self,wiring = None,name=None,model=None,date=None):
-    if wiring != None:
-      self.wiring = wiring
-    else:
-      self.wiring = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-   
-    self.name = name
-      
-    self.model = model
-      
-    self.date = date
-   
-  def __getattr__(self,name):
-    return self.__dict__[name]
+
+class Reflector(object):
+    def __init__(self, wiring=None, name=None, model=None, date=None):
+        if wiring != None:
+            self.wiring = wiring
+        else:
+            self.wiring="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        self.name = name
+        self.model = model
+        self.date = date
+
+    def __getattr__(self, name):
+        return self.__dict__[name]
+
+    def __setattr__(self, name, value):
+        self.__dict__[name] = value
+
+    def encipher (self, key):
+        shift = (ord(self.state) - ord('A'))
+        index = (ord(key) - ord('A'))%26 # true index
+        index = (index + shift)%26 # actual connector hit
+
+        letter = self.wiring[index] # rotor letter generated
+        out = chr(ord('A')+(ord(letter) - ord('A') +26 - shift)%26) # actual output
+        #return letter
+        return out
+
+    def __eq__(self,rotor):
+        return self.name == rotor.name
+
+class Rotor(object):
+    def __init__(self, wiring=None, notchs=None, name=None, model=None, date=None, state="A"):
+        if wiring != None:
+            self.wiring = wiring
+        else:
+            self.wiring="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+        self.rwiring = ["0"] * 26
+        for i in range(0, len(self.wiring)):
+            self.rwiring[ord(self.wiring[i]) - ord('A')]= chr(ord('A') + i)
+        if notchs != None:
+            self.notchs = notchs
+        else:
+            self.notchs = ""
+        self.name = name
+        self.model = model
+        self.date = date
+        self.state = state
+
+    def __getattr__(self, name):
+        return self.__dict__[name]
+
+    def __setattr__(self, name, value):
+        self.__dict__[name] = value
+        if name == 'wiring':
+            self.rwiring = ["0"]*26
+            for i in range(0,len(self.wiring)):
+                self.rwiring[ord(self.wiring[i]) - ord('A')] = chr(ord('A')+i)
+
+    def encipher_right(self, key):
+        shift = (ord(self.state) - ord('A'))
+        index = (ord(key) - ord('A'))%26 # true index
+        index = (index + shift)%26 # actual connector hit
     
-  def __setattr__(self,name,value):
-    self.__dict__[name] = value
-   
-  def encipher (self, key):
-    shift = (ord(self.state) - ord('A'))
-    index = (ord(key) - ord('A'))%26 # true index
-    index = (index + shift)%26 # actual connector hit
-    
-    letter = self.wiring[index] # rotor letter generated
-    out = chr(ord('A')+(ord(letter) - ord('A') +26 - shift)%26) # actual output
-    #return letter
-    return out
-    
-  def __eq__(self,rotor):
-    return self.name == rotor.name
+        letter = self.wiring[index] # rotor letter generated
+        out = chr(ord('A')+(ord(letter) - ord('A') +26 - shift)%26) # actual output
+        #return letter
+        return out
 
-class Rotor:
-  def __init__(self,wiring = None,notchs =None,name=None,model=None,date=None,state="A",):
-    if wiring != None:
-      self.wiring = wiring
-    else:
-      self.wiring = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    self.rwiring = ["0"]*26
-    for i in range(0,len(self.wiring)):
-      self.rwiring[ord(self.wiring[i]) - ord('A')]= chr(ord('A')+i)
-    if notchs != None:
-      self.notchs = notchs
-    else:
-      self.notchs = ""
-      
-    self.name = name
-      
-    self.model = model
-      
-    self.date = date
-      
-    self.state = state
+    def encipher_left(self, key):
+        shift = (ord(self.state) - ord('A'))
+        index = (ord(key) - ord('A'))%26
+        index = (index + shift)%26
+        #index = (index )%26
+        letter = self.rwiring[index]
+        #letter = chr((ord(self.rwiring[index]) -ord('A') + 26 -shift)%26+ord('A'))
+        out = chr(ord('A')+(ord(letter) - ord('A') + 26 - shift)%26)
+        #return letter
+        return out
 
-   
-  def __getattr__(self,name):
-    return self.__dict__[name]
-    
-  def __setattr__(self,name,value):
-    self.__dict__[name] = value
-    if name == 'wiring':
-      self.rwiring = ["0"]*26
-      for i in range(0,len(self.wiring)):
-        self.rwiring[ord(self.wiring[i]) - ord('A')]= chr(ord('A')+i)
-   
-  def encipher_right (self, key):
-    shift = (ord(self.state) - ord('A'))
-    index = (ord(key) - ord('A'))%26 # true index
-    index = (index + shift)%26 # actual connector hit
-    
-    letter = self.wiring[index] # rotor letter generated
-    out = chr(ord('A')+(ord(letter) - ord('A') +26 - shift)%26) # actual output
-    #return letter
-    return out
-  
-  def encipher_left (self, key):
-    shift = (ord(self.state) - ord('A')) 
-    index = (ord(key) - ord('A'))%26
-    index = (index + shift)%26
-    #index = (index )%26
-    letter = self.rwiring[index]
-    #letter = chr((ord(self.rwiring[index]) -ord('A') + 26 -shift)%26+ord('A'))
-    out = chr(ord('A')+(ord(letter) - ord('A') + 26 - shift)%26)
-    #return letter
-    return out
-  
-  def notch (self, offset = 1):
-    self.state = chr((ord(self.state) + offset -ord('A'))%26 +ord('A'))
-    notchnext = self.state in self.notchs
-    #return notchnext
-   
-  def is_in_turnover_pos (self):
-    return chr((ord(self.state) + 1 -ord('A'))%26 +ord('A')) in self.notchs
-    
-  def __eq__(self,rotor):
-    return self.name == rotor.name
+    def notch(self, offset=1):
+        self.state = chr((ord(self.state) + offset - ord('A')) % 26 + ord('A'))
+        notchnext = self.state in self.notchs
+        #return notchnext
+
+    def is_in_turnover_pos(self):
+        return chr((ord(self.state) + 1 - ord('A')) % 26 + ord('A')) in self.notchs
+
+    def __eq__(self, rotor):
+        return self.name == rotor.name
 
 # 1924 Rotors
-ROTOR_IC = Rotor(wiring = "DMTWSILRUYQNKFEJCAZBPGXOHV",name="IC",model="Commercial Enigma A, B",date="1924")
-ROTOR_IIC = Rotor(wiring = "HQZGPJTMOBLNCIFDYAWVEUSRKX",name="IIC",model="Commercial Enigma A, B",date="1924")
-ROTOR_IIIC = Rotor(wiring = "UQNTLSZFMREHDPXKIBVYGJCWOA",name="IIIC",model="Commercial Enigma A, B",date="1924")
+ROTOR_IC = Rotor(wiring="DMTWSILRUYQNKFEJCAZBPGXOHV", name="IC", model="Commercial Enigma A, B", date="1924")
+ROTOR_IIC = Rotor(wiring="HQZGPJTMOBLNCIFDYAWVEUSRKX", name="IIC", model="Commercial Enigma A, B", date="1924")
+ROTOR_IIIC = Rotor(wiring="UQNTLSZFMREHDPXKIBVYGJCWOA", name="IIIC", model="Commercial Enigma A, B", date="1924")
 
 
 # German Railway Rotors
-ROTOR_GR_I = Rotor(wiring = "JGDQOXUSCAMIFRVTPNEWKBLZYH",name="I",model="German Railway (Rocket)",date="7 February 1941")
-ROTOR_GR_II = Rotor(wiring = "NTZPSFBOKMWRCJDIVLAEYUXHGQ",name="II",model="German Railway (Rocket)",date="7 February 1941")
-ROTOR_GR_III = Rotor(wiring = "JVIUBHTCDYAKEQZPOSGXNRMWFL",name="III",model="German Railway (Rocket)",date="7 February 1941")
-ROTOR_GR_UKW = Reflector(wiring = "QYHOGNECVPUZTFDJAXWMKISRBL",name="UTKW",model="German Railway (Rocket)",date="7 February 1941")
-ROTOR_GR_ETW = Rotor(wiring = "QWERTZUIOASDFGHJKPYXCVBNML",name="ETW",model="German Railway (Rocket)",date="7 February 1941")
+ROTOR_GR_I = Rotor(wiring="JGDQOXUSCAMIFRVTPNEWKBLZYH", name="I", model="German Railway (Rocket)", date="7 February 1941")
+ROTOR_GR_II = Rotor(wiring="NTZPSFBOKMWRCJDIVLAEYUXHGQ", name="II", model="German Railway (Rocket)", date="7 February 1941")
+ROTOR_GR_III = Rotor(wiring="JVIUBHTCDYAKEQZPOSGXNRMWFL", name="III", model="German Railway (Rocket)", date="7 February 1941")
+ROTOR_GR_UKW = Reflector(wiring="QYHOGNECVPUZTFDJAXWMKISRBL", name="UTKW", model="German Railway (Rocket)", date="7 February 1941")
+ROTOR_GR_ETW = Rotor(wiring="QWERTZUIOASDFGHJKPYXCVBNML", name="ETW", model="German Railway (Rocket)", date="7 February 1941")
 
 # Swiss K Rotors
-ROTOR_I_K = Rotor(wiring = "PEZUOHXSCVFMTBGLRINQJWAYDK",name="I-K",model="Swiss K",date="February 1939")
-ROTOR_II_K = Rotor(wiring = "ZOUESYDKFWPCIQXHMVBLGNJRAT",name="II-K",model="Swiss K",date="February 1939")
-ROTOR_II_K = Rotor(wiring = "EHRVXGAOBQUSIMZFLYNWKTPDJC",name="III-K",model="Swiss K",date="February 1939")
-ROTOR_UKW_K = Reflector(wiring = "IMETCGFRAYSQBZXWLHKDVUPOJN",name="UKW-K",model="Swiss K",date="February 1939")
-ROTOR_ETW_K = Rotor(wiring = "QWERTZUIOASDFGHJKPYXCVBNML",name="ETW-K",model="Swiss K",date="February 1939")
+ROTOR_I_K = Rotor(wiring="PEZUOHXSCVFMTBGLRINQJWAYDK", name="I-K", model="Swiss K", date="February 1939")
+ROTOR_II_K = Rotor(wiring="ZOUESYDKFWPCIQXHMVBLGNJRAT", name="II-K", model="Swiss K", date="February 1939")
+ROTOR_II_K = Rotor(wiring="EHRVXGAOBQUSIMZFLYNWKTPDJC", name="III-K", model="Swiss K", date="February 1939")
+ROTOR_UKW_K = Reflector(wiring="IMETCGFRAYSQBZXWLHKDVUPOJN", name="UKW-K", model="Swiss K", date="February 1939")
+ROTOR_ETW_K = Rotor(wiring="QWERTZUIOASDFGHJKPYXCVBNML", name="ETW-K", model="Swiss K", date="February 1939")
 
 # Enigma
-ROTOR_I = Rotor(wiring = "EKMFLGDQVZNTOWYHXUSPAIBRCJ",notchs="R",name="I",model="Enigma 1",date="1930")
-ROTOR_II = Rotor(wiring = "AJDKSIRUXBLHWTMCQGZNPYFVOE",notchs="F",name="II",model="Enigma 1",date="1930")
-ROTOR_III = Rotor(wiring = "BDFHJLCPRTXVZNYEIWGAKMUSQO",notchs="W",name="III",model="Enigma 1",date="1930")
-ROTOR_IV = Rotor(wiring = "ESOVPZJAYQUIRHXLNFTGKDCMWB",notchs="K",name="VI",model="M3 Army",date="December 1938")
-ROTOR_V = Rotor(wiring = "VZBRGITYUPSDNHLXAWMJQOFECK",notchs="A",name="V",model="M3 Army",date="December 1938")
-ROTOR_VI = Rotor(wiring = "JPGVOUMFYQBENHZRDKASXLICTW",notchs="AN",name="VI",model="M3 & M4 Naval(February 1942)",date="1939")
-ROTOR_VII = Rotor(wiring = "NZJHGRCXMYSWBOUFAIVLPEKQDT",notchs="AN",name="VII",model="M3 & M4 Naval(February 1942)",date="1939")
-ROTOR_VIII = Rotor(wiring = "FKQHTLXOCBJSPDZRAMEWNIUYGV",notchs="AN",name="VIII",model="M3 & M4 Naval(February 1942)",date="1939")
+ROTOR_I = Rotor(wiring="EKMFLGDQVZNTOWYHXUSPAIBRCJ",notchs="R", name="I", model="Enigma 1", date="1930")
+ROTOR_II = Rotor(wiring="AJDKSIRUXBLHWTMCQGZNPYFVOE",notchs="F", name="II", model="Enigma 1", date="1930")
+ROTOR_III = Rotor(wiring="BDFHJLCPRTXVZNYEIWGAKMUSQO",notchs="W", name="III", model="Enigma 1", date="1930")
+ROTOR_IV = Rotor(wiring="ESOVPZJAYQUIRHXLNFTGKDCMWB",notchs="K", name="VI", model="M3 Army", date="December 1938")
+ROTOR_V = Rotor(wiring="VZBRGITYUPSDNHLXAWMJQOFECK",notchs="A", name="V", model="M3 Army", date="December 1938")
+ROTOR_VI = Rotor(wiring="JPGVOUMFYQBENHZRDKASXLICTW",notchs="AN", name="VI", model="M3 & M4 Naval(February 1942)", date="1939")
+ROTOR_VII = Rotor(wiring="NZJHGRCXMYSWBOUFAIVLPEKQDT",notchs="AN", name="VII", model="M3 & M4 Naval(February 1942)", date="1939")
+ROTOR_VIII = Rotor(wiring="FKQHTLXOCBJSPDZRAMEWNIUYGV",notchs="AN", name="VIII", model="M3 & M4 Naval(February 1942)", date="1939")
 
 # misc & reflectors
-ROTOR_Beta = Rotor(wiring = "LEYJVCNIXWPBQMDRTAKZGFUHOS",name="Beta",model="M4 R2",date="Spring 1941")
-ROTOR_Gamma = Rotor(wiring = "FSOKANUERHMBTIYCWLQPZXVGJD",name="Gamma",model="M4 R2",date="Spring 1941")
-ROTOR_Reflector_A = Reflector(wiring = "EJMZALYXVBWFCRQUONTSPIKHGD",name="Reflector A")
-ROTOR_Reflector_B = Reflector(wiring = "YRUHQSLDPXNGOKMIEBFZCWVJAT",name="Reflector B")
-ROTOR_Reflector_C = Reflector(wiring = "FVPJIAOYEDRZXWGCTKUQSBNMHL",name="Reflector C")
-ROTOR_Reflector_B_Thin = Reflector(wiring = "ENKQAUYWJICOPBLMDXZVFTHRGS",name="Reflector_B_Thin",model="M4 R1 (M3 + Thin)",date="1940")
-ROTOR_Reflector_C_Thin = Reflector(wiring = "RDOBJNTKVEHMLFCWZAXGYIPSUQ",name="Reflector_C_Thin",model="M4 R1 (M3 + Thin)",date="1940")
-ROTOR_ETW = Rotor(wiring = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",name="ETW",model="Enigma 1")
-
+ROTOR_Beta = Rotor(wiring="LEYJVCNIXWPBQMDRTAKZGFUHOS", name="Beta", model="M4 R2", date="Spring 1941")
+ROTOR_Gamma = Rotor(wiring="FSOKANUERHMBTIYCWLQPZXVGJD", name="Gamma", model="M4 R2", date="Spring 1941")
+ROTOR_Reflector_A = Reflector(wiring="EJMZALYXVBWFCRQUONTSPIKHGD", name="Reflector A")
+ROTOR_Reflector_B = Reflector(wiring="YRUHQSLDPXNGOKMIEBFZCWVJAT", name="Reflector B")
+ROTOR_Reflector_C = Reflector(wiring="FVPJIAOYEDRZXWGCTKUQSBNMHL", name="Reflector C")
+ROTOR_Reflector_B_Thin = Reflector(wiring="ENKQAUYWJICOPBLMDXZVFTHRGS", name="Reflector_B_Thin", model="M4 R1 (M3 + Thin)", date="1940")
+ROTOR_Reflector_C_Thin = Reflector(wiring="RDOBJNTKVEHMLFCWZAXGYIPSUQ", name="Reflector_C_Thin", model="M4 R1 (M3 + Thin)", date="1940")
+ROTOR_ETW = Rotor(wiring="ABCDEFGHIJKLMNOPQRSTUVWXYZ", name="ETW", model="Enigma 1")