Advertisement
paulogp

Cifra Enigma

Aug 7th, 2011
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.55 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. # Uma implementação da cifra Enigma
  3. # Autor: Bruno Flávio de Castro Ribeiro
  4. # A Criptanálise da ENIGMA: 1932-1939
  5. # Tese 217
  6.  
  7. # Exemplo
  8. # Rotores utilizados: III, II e I (posicao direita, meio e esquerda respectivamente)
  9. # Posicoes: P, J e D
  10. # Aneis ajustados para as posicoes: K, W e D
  11. #
  12. # x = enigma([rotor(rotorIII), rotor(rotorII), rotor(rotorI)], 'KWD', 'PJD', 'WFR', plugboard(painel1), mirror(reflectorB))
  13. # x.egm('MAQUINAENIGMA')
  14.  
  15. # Componentes da Enigma
  16. import exceptions
  17.  
  18. class unsoundComponent(Exception):
  19.     pass
  20.  
  21. class unsoundPlugboard(Exception):
  22.     pass
  23.  
  24. class Ething(object):
  25.     def verify(self):
  26.         foo = {}
  27.         for i in self.table.keys():
  28.             foo[self.table[i]] = True
  29.  
  30.         if len(self.table.keys()) != 26 or len(foo.keys()) != 26:
  31.             raise unsoundComponent
  32.  
  33.     def trad(self, c):
  34.         return self.table[c]
  35.  
  36.     def tradinv(self, c):
  37.         return self.tableinv[c]
  38.  
  39.     def tord(self, c):
  40.         return ord(c) - ord('A')
  41.  
  42.     def mostra(self, c):
  43.         return self.table
  44.  
  45. class rotor(Ething):
  46.     def __init__(self, perm):
  47.         self.table = {}
  48.         self.tableinv = {}
  49.         foo = 0
  50.        
  51.         for i in perm:
  52.             self.table[foo] = self.tord(i)
  53.             foo = foo + 1
  54.         self.verify()
  55.        
  56.         for j in range(len(self.table.keys())):
  57.             self.tableinv[self.table.values()[j]] = self.table.keys()[j]
  58.         self.verify()
  59.  
  60. class mirror(Ething):
  61.     def __init__(self, perm):
  62.         self.table = {}
  63.        
  64.         for i in perm:
  65.             self.table[self.tord(i[0])] = self.tord(i[1])
  66.             self.table[self.tord(i[1])] = self.tord(i[0])
  67.         self.verify()
  68.  
  69. class plugboard(Ething):
  70.     def __init__(self, perm):
  71.         self.table = {}
  72.         for i in range(26):
  73.             self.table[i] = i
  74.  
  75.         for i in perm:
  76.             self.table[self.tord(i[0])] = self.tord(i[1])
  77.             self.table[self.tord(i[1])] = self.tord(i[0])
  78.         self.verify()
  79.         self.verifyplugboard()
  80.  
  81.     def verifyplugboard(self):
  82.         foo = {}
  83.         for i in range(len(self.table.keys())):
  84.             if self.table[i] != i:
  85.                 foo[i] = True
  86.  
  87.         if len(foo.keys()) > 20:
  88.             raise unsoundPlugboard
  89.  
  90. # Plugboards, rotores e reflectores da Enigma
  91. painel0 = []
  92. painel1 = ['UA', 'PF', 'RQ', 'SO', 'NI', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  93. painel2 = ['UB', 'PS', 'RQ', 'FO', 'NY', 'EI', 'AG', 'HL', 'TX', 'ZJ']
  94. painel3 = ['UC', 'PF', 'RQ', 'SO', 'NI', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  95. painel4 = ['UO', 'PF', 'RQ', 'SA', 'NI', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  96. painel5 = ['UP', 'AF', 'RQ', 'SO', 'NI', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  97. painel6 = ['UH', 'PF', 'RQ', 'SO', 'NI', 'EY', 'BG', 'AL', 'TX', 'ZJ']
  98. painel7 = ['UX', 'PF', 'RQ', 'SO', 'NI', 'EY', 'BG', 'HL', 'TA', 'ZJ']
  99. painel8 = ['UI', 'PF', 'RQ', 'SO', 'NA', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  100. painel9 = ['EA', 'PF', 'RQ', 'SO', 'NI', 'UY', 'BG', 'HL', 'TX', 'ZJ']
  101. painel10 = ['UA', 'RF', 'PQ', 'SO', 'NI', 'EY', 'BG', 'HL', 'TX', 'ZJ']
  102.  
  103. rotorI = 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'
  104. rotorII = 'AJDKSIRUXBLHWTMCQGZNPYFVOE'
  105. rotorIII = 'BDFHJLCPRTXVZNYEIWGAKMUSQO'
  106. rotorIV = 'ESOVPZJAYQUIRHXLNFTGKDCMWB'
  107. rotorV = 'VZBRGITYUPSDNHLXAWMJQOFECK'
  108.  
  109. reflectorB = ['AY', 'BR', 'CU', 'DH', 'EQ', 'FS', 'GL', 'IP', 'JX', 'KN', 'MO', 'TZ', 'VW']
  110. reflectorC = ['AF', 'BV', 'CP', 'DJ', 'EI', 'GO', 'HY', 'KR', 'LZ', 'MX', 'NW', 'TQ', 'SU']
  111.  
  112. # Movimento da Enigma
  113. def Rot(c, s, i, e, n, t):
  114.     return (c + s[t] + R(t, n, i, e)) % 26
  115.  
  116. def Roti(c, s, i, e, n, t):
  117.     return (c - s[t] - R(t, n, i, e)) % 26
  118.  
  119. def R(t, n, i, e):
  120.     if t == 0:
  121.         return n + 1
  122.     else:
  123.         if t == 1 and i[t] + ((i[t-1] - e[t-1]) % 26 + n) / 26 == e[t] - 1:
  124.             return ((i[t-1] - e[t-1]) % 26 + R(t - 1, n, i, e)) / 26 + 1
  125.         else:
  126.             return ((i[t-1] - e[t-1]) % 26 + R(t - 1, n, i, e)) / 26
  127.  
  128. class enigma:
  129.     def __init__(self, rotlist, rings, pinit, notch, painel, reflector):
  130.         self.rotlist = rotlist
  131.         self.rings = rings
  132.         self.pinit = pinit
  133.         self.notch = notch
  134.         self.painel = painel
  135.         self.reflector = reflector
  136.  
  137.     def egm(self, msg):
  138.         msgcod = ''
  139.         lplaint = [0 for i in range(len(msg))]
  140.         pinitial = [0 for i in range(len(self.pinit))]
  141.         rings = [0 for i in range(len(self.rings))]
  142.         shift = [0 for i in range(len(self.rings))]
  143.         notch = [0 for i in range(len(self.notch))]
  144.         codtext = {}
  145.  
  146.         for n in range(len(msg)):
  147.             lplaint[n] = ord(msg[n]) - ord('A')
  148.             c0 = self.painel.trad(lplaint[n])
  149.             ct = c0
  150.  
  151.             for j in range(len(self.rotlist)):
  152.                 pinitial[j] = ord(self.pinit[j]) - ord('A')
  153.                 rings[j] = ord(self.rings[j]) - ord('A')
  154.                 shift[j] = (pinitial[j] - rings[j]) % 26
  155.                 notch[j] = ord(self.notch[j]) - ord('A')
  156.  
  157.                 c1 = Rot(ct, shift, pinitial, notch, n, j)
  158.                 c2 = self.rotlist[j].trad(c1)
  159.                 c3 = Roti(c2, shift, pinitial, notch, n, j)
  160.                 ct = c3
  161.  
  162.             cr = self.reflector.trad(ct)
  163.  
  164.             for k in range(len(self.rotlist)):
  165.                 c_1 = Rot(cr, shift, pinitial, notch, n, len(self.rotlist) - 1 - k)
  166.                 c_2 = self.rotlist[len(self.rotlist) - 1 - k].tradinv(c_1)
  167.                 c_3 = Roti(c_2, shift, pinitial, notch, n, len(self.rotlist) - 1 - k)
  168.                 cr = c_3
  169.  
  170.             cf = self.painel.trad(cr)
  171.             codtext[lplaint[n]] = cf
  172.             msgcod = msgcod + chr(cf + 65)
  173.            
  174.         return msgcod
  175.  
  176. # As seis permutacoes diarias
  177. alfa = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  178.  
  179. def state():
  180.     R = []
  181.     H = []
  182.  
  183.     for k in alfa:
  184.         for s in alfa:
  185.             for t in alfa:
  186.                 pinit = k + s + t
  187.  
  188.                 for j in range(6):
  189.                     L = []
  190.                     A = num2let((let2num(pinit[0]) + j) % 26)
  191.                     B = pinit[1]
  192.                     C = pinit[2]
  193.                     pin = A + B + C
  194.                     notch = num2let((let2num(pin[0]) + 7) % 26) + num2let((let2num(pin[1]) + 7) % 26) + 'A'
  195.  
  196.                     for i in alfa:
  197.                         x = enigma([rotor(rotorII), rotor(rotorIII), rotor(rotorI)], 'AAA', pin, notch, plugboard(painel0), mirror(reflectorB))
  198.                         y = x.egm(i)
  199.                         L.append(i)
  200.                         L.append(y)
  201.                         W = list2dict(L)
  202.                         R.append(W)
  203.  
  204.                     H.append(R)
  205.                     R = []
  206.     return H
  207.  
  208. def list2dict(L):
  209.     D = {}
  210.     c = len(L)
  211.     for r in range(c):
  212.         D[L[(2 * r) % c]] = L[(2 * r + 1) % c]
  213.  
  214.     return D
  215.  
  216. def let2num(A):
  217.     return ord(A) - 65
  218.  
  219. def num2let(A):
  220.     return chr((A % 26 + 65))
  221.  
  222. # Ciclometro
  223. # PS: processo 30m aprox
  224. import pickle
  225.  
  226. f = open('catalogo.pck', 'w')
  227. alfa = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  228.  
  229. def ciclometer():
  230.     C = []
  231.     for a in range(len(alfa)):
  232.         for b in range(len(alfa)):
  233.             for c in range(len(alfa)):
  234.                 pinit1 = alfa[a] + alfa[b] + alfa[c]
  235.                 pinit2 = num2let(let2num(pinit1[0]) + 3) + pinit1[1:3]
  236.                 A, B, D = [], [], []
  237.                 notch = num2let(let2num(pinit1[0]) + 7) + num2let(let2num(pinit1[1]) + 7) + 'A'
  238.  
  239.                 for i in range(len(alfa)):
  240.                     if alfa[i] not in B:
  241.                         let = alfa[i]
  242.                         X = [let]
  243.                         lit = ''
  244.                         while lit != X[0]:
  245.                             x = enigma([rotor(rotorIII), rotor(rotorII), rotor(rotorI)], 'AAA', pinit1, notch, plugboard(painel0), mirror(reflectorB))
  246.                             w = enigma([rotor(rotorIII), rotor(rotorII), rotor(rotorI)], 'AAA', pinit2, notch, plugboard(painel0), mirror(reflectorB))
  247.  
  248.                         y = x.egm(let)
  249.                         z = w.egm(y)
  250.                         X.append(y)
  251.                         X.append(z)
  252.                         let = z
  253.                         lit = let
  254.                     B = B + X
  255.                     A.append(X[0:len(X) - 1])
  256.  
  257.                 D = D + A
  258.                 W = [len(D) * 2]
  259.  
  260.                 for i in range(len(D)):
  261.                     W = W + [len(D[i]) / 2] + [len(D[i]) / 2]
  262.                     C.append(W + [pinit1])
  263.                    
  264.     pickle.dump(C, f)
  265.     f.close()
  266.  
  267. def let2num(A):
  268.     return ord(A) - 65
  269.  
  270. def num2let(A):
  271.     return chr((A % 26 + 65))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement