def test(self): #print (self.grundStellung) grunds = self.decodeGrundStellung() enigmai = Enigma( rotors={ 1: Rotor("VIII", 19 - 1, pomlist.index(grunds[0])), #slowest, left-most 2: Rotor("II", 7 - 1, pomlist.index(grunds[1])), #middle 3: Rotor("IV", 12 - 1, pomlist.index(grunds[2])), #fastest, right-most }, reflector=Reflector("B"), plugboard=Plugboard({ "B": "D", "C": "O", "E": "I", "G": "L", "J": "S", "K": "T", "N": "V", "P": "M", "Q": "R", "W": "Z" })) text = enigmai.EDcrypt(self.ttc) print("DECRYPTED TEXT: " + text) print("STECKERS: %s" % enigmai.plugboard.wiring)
def __init__(self, key='AAA', swaps=None, rotor_order=['I', 'II', 'III']): ''' Initializes the Enigma machine. key = Three letter string specifying the top/visible letter for the left, middle, and right rotors respectively. This determines indexing in the rotor. swaps = Specifies which plugboard swaps you would like to implement, if any. These should be provided in the form [('A', 'B'), ('T', 'G')] if you want to swap A,B and T,G. rotor_order = Defines which rotor to set as the left, middle, and right rotors respectively when considering the Enigma geometrically as described above. ''' if len(key) != 3: print( 'Please provide a three letter string as the initial window setting.' ) return None # Set the key and rotor order. self.key = key self.rotor_order = rotor_order # Now define the components. self.r_rotor = Rotor(rotor_order[2], key[2]) self.m_rotor = Rotor(rotor_order[1], key[1], self.r_rotor) self.l_rotor = Rotor(rotor_order[0], key[0], self.m_rotor) self.reflector = Reflector() self.plugboard = Plugboard(swaps) # Define prev_rotor information for middle and right rotors. self.m_rotor.prev_rotor = self.l_rotor self.r_rotor.prev_rotor = self.m_rotor
def decodeGrundStellung(self): #find out the starting grund stellung if we know the other parts enigmai = Enigma( rotors={ 1: Rotor("VIII", 19 - 1, pomlist.index( self.grundStellung[0])), #slowest, left-most 2: Rotor("II", 7 - 1, pomlist.index(self.grundStellung[1])), #middle 3: Rotor("IV", 12 - 1, pomlist.index( self.grundStellung[2])), #fastest, right-most }, reflector=Reflector("B"), plugboard=Plugboard({ "B": "D", "C": "O", "E": "I", "G": "L", "J": "S", "K": "T", "N": "V", "P": "M", "Q": "R", "W": "Z" })) text = enigmai.EDcrypt(self.grundStellung[3:]) return text
def test_Rotor_doublestep(): B = Rotor('II', 'e') A = Rotor('I', 'a', B) B_offset = B.offset A.step() assert B.offset == (B_offset + 1) % 26 assert B.window == ALPHABET[(B_offset + 1) % 26]
def ultimate_MP_method_1_GRUND_EXHAUSTION(self): # 2nd step is to find out the plausible grund settings as candidates for Hill Climbing scorer = scorer_ic() candidate = self.subset.split(';') #print (candidate[0]) #strtowrite = "!!! Starting at " +format(datetime.now(), '%H:%M:%S')+ " with: "+ self.subset[0]+"-"+self.subset[1]+"-"+ self.subset[2] #self.q.put(strtowrite) print("!!! Starting at " + format(datetime.now(), '%H:%M:%S') + " with: " + candidate[0] + "-" + candidate[1] + "-" + candidate[2] + "-" + candidate[3]) messagelenght = len(self.ttc) myIC = 0 topIC = float(candidate[0]) # initliaze empty enigma for further re-use enigmai = Enigma() enigmai.reflector = Reflector("B" if int(candidate[4]) == 0 else "C") for i in range(1): for j in range(26): for k in range(26): #start = time() rotors = { # i,j,k = rings # l = fastest grund / offset 1: Rotor(candidate[1], int(candidate[5]), i), #slowest, left-most 2: Rotor(candidate[2], int(candidate[6]), j), #middle 3: Rotor(candidate[3], int(candidate[7]), k), #fastest, right-most } enigmai.rotors = rotors text = enigmai.EDcrypt(self.ttc) myIC = scorer.score(text, messagelenght) #print (myIC) if myIC >= topIC: topIC = myIC topGrundSlow = i topGrundMiddle = j topGrundFast = k topText = text #print (topText) if (myIC > topIC): strtowrite = str(candidate[0]) + ";" + str(topIC) + ";" + rotors[ 1].number + ";" + rotors[2].number + ";" + rotors[ 3].number + ";" + str(topGrundSlow) + ";" + str( topGrundMiddle) + ";" + str(topGrundFast) self.q.put(strtowrite) else: pass
def test_Rotor_init(): A = Rotor('I', 'a') assert A.rotor_num == 'I' assert A.wiring == ROTOR_WIRINGS['I'] assert A.notch == ROTOR_NOTCHES['I'] assert A.window == 'A' assert A.offset == 0 assert A.next_rotor == None assert A.prev_rotor == None with pytest.raises(ValueError): Fail = Rotor("", "")
def set_rotor_order(self, rotor_order): ''' Changes the order of rotors in the Engima machine to match that specified by the user. The syntax for the rotor order is a list of the form ['I', 'II', 'III'], where 'I' is the left rotor, 'II' is the middle rotor, and 'III' is the right rotor. ''' # Now define the components. self.l_rotor = Rotor(rotor_order[0], self.key[0]) self.m_rotor = Rotor(rotor_order[1], self.key[1], self.l_rotor) self.r_rotor = Rotor(rotor_order[2], self.key[2], self.m_rotor) # Define prev_rotor information for middle and left rotors. self.m_rotor.prev_rotor = self.r_rotor self.l_rotor.prev_rotor = self.m_rotor
def test_Rotor_step_with_second_rotor(): B = Rotor('II', 'a') A = Rotor('I', 'Q', B) B_offset = B.offset A_offset = A.offset A.step() assert B.offset == (B_offset + 1) % 26 assert B.window == ALPHABET[(B_offset + 1) % 26] assert A.offset == (A_offset + 1) % 26 assert A.window == ALPHABET[(A_offset + 1) % 26]
def test_Rotor_encode_letters_forward_next(): C = Rotor('III', 'a') B = Rotor('II', 'a') A = Rotor('I', 'a') index = ALPHABET.index('a'.upper()) A.next_rotor = B B.prev_rotor = A B.next_rotor = C ret = B.encode_letter('a', forward=True) output_letter = B.wiring['forward'][(index + B.offset) % 26] output_index = (ALPHABET.index(output_letter) - B.offset) % 26 assert ret == B.next_rotor.encode_letter(output_index, True)
def buildenigma(fn): """ Builds an Enigma object from the given file object. Returns the Enigma object. """ plugboard = [i for i in range(Plugboard.PLUGBOARD_LENGTH)] rotors = [] notches = [] reflector = [] offsets = [] for i in fn: i = i.strip().split() if i[0] == "ROTOR": rotors.append([int(j) for j in i[2:]]) offsets.append(0) elif i[0] == "PLUGBOARD": pb = [int(j) for j in i[2:]] elif i[0] == "NOTCHES": notches = [int(j) for j in i[2:]] elif i[0] == "REFLECTOR": reflector = [int(j) for j in i[2:]] elif i[0] == "OFFSETS": offsets = [int(j) for j in i[2:]] PLUGBOARD = Plugboard(plugboard) ROTORS = [Rotor(i[0], i[1]) for i in zip(rotors, offsets)] REFLECTOR = Reflector(reflector) SHAFT = Shaft(ROTORS, notches, REFLECTOR) return Enigma(SHAFT, PLUGBOARD)
def test_Rotor_step_no_second_rotor(): A = Rotor('I', 'a') A_offset = A.offset A.step() assert A.offset == (A_offset + 1) % 26 assert A.window == ALPHABET[(A_offset + 1) % 26]
def test_Rotor_encode_letters_forward_nothing(): A = Rotor('I', 'a') ret = A.encode_letter('a') index = ALPHABET.index('a'.upper()) output_letter = A.wiring['forward'][(index + A.offset) % 26] output_index = (ALPHABET.index(output_letter) - A.offset) % 26 assert ret == output_index
def test_Rotor_encode_letters_forward_return_letter(): A = Rotor('I', 'a') ret = A.encode_letter('a', return_letter=True) index = ALPHABET.index('a'.upper()) output_letter = A.wiring['forward'][(index + A.offset) % 26] output_index = (ALPHABET.index(output_letter) - A.offset) % 26 assert ret == ALPHABET[output_index] assert A.encode_letter('a', printit=True)
def setup_method(self): self.rotor_l = Rotor("I", "P") self.rotor_m = Rotor("II", "D", next_rotor=self.rotor_l) self.rotor_r = Rotor("III", "U", next_rotor=self.rotor_m) self.rotor_l.prev_rotor = self.rotor_m self.rotor_m.prev_rotor = self.rotor_r
def test_invalid_rotor(self): with pytest.raises(ValueError) as err: Rotor("IV", "A") print(err)
def test_Rotor_repr(): A = Rotor('I', 'a', 'II', 'III') assert A.__repr__() == 'Window: A'
def testHillClimb(self): #print ("testHillClimb") bestoftherun = -10000 bestoftherunIC = -10000 bestoftherunGRAM = -10000 myscore = -10000 steckerscoreIC = -10000 steckerscoreGRAM = -10000 steckerscoreAIC = -10000 steckerinfo = [] plugsIC = 4 #how many plugs we'd like to try to find in 1st run IC plugsGRAM = 6 #how many plugs we'd like to try to find in 2nd run trigram plugs3 = 0 #how many plugs we'd like to try to find in 3rd run trigram f = open("testHillClimb.txt", 'a') start = datetime.now() f.write("\n\nSTART: " + format(start, '%H:%M:%S') + "\n\n") f.flush() grunds = self.decodeGrundStellung() plugboardi = Plugboard() reflectori = Reflector("B") rotors = { 1: Rotor("VIII", 19 - 1, pomlist.index(grunds[0])), #slowest, left-most 2: Rotor("II", 7 - 1, pomlist.index(grunds[1])), #middle 3: Rotor("IV", 12 - 1, pomlist.index(grunds[2])), #fastest, right-most } enigmai = Enigma(rotors, reflectori, plugboardi) print(enigmai) text = enigmai.EDcrypt(self.ttc) myic = self.scorer_IC.score(text) print("Original IC / plain text (before heuristics): " + str(myic)) startTime = time() steckerscoreIC, steckerscoreGRAM, steckerscoreAIC, steckerinfo = self.steckerHillClimbTest( rotors, reflectori, myic, plugsIC, plugsGRAM) print("Execution time is: %.3fs" % (time() - startTime)) print("\nScores\n" + "Original IC:" + str(myic) + "\nAfterwards IC:" + str(steckerscoreAIC) + "\nTrigram:" + str(steckerscoreGRAM)) print("End of heuristics\n\n") print("Heuristics results:") if ((steckerscoreIC > bestoftherunIC and steckerscoreAIC > 0.05) or (steckerscoreGRAM > bestoftherunGRAM and steckerscoreAIC > 0.06)): #print ("CHECKTHISOUT: " +text+"\n") bestoftherunIC = steckerscoreIC bestoftherunGRAM = steckerscoreGRAM #print ("\nScores\n"+"Original IC:"+str(steckerscoreIC)+"\nAfterwards IC:"+str(steckerscoreAIC)+"\nTrigram:"+str(steckerscoreGRAM)) #print (str(steckerinfo)) #print ("TEXT: " +text+"\n") if steckerscoreAIC > 0.065: print("BINGO IC!!! " + str(steckerscoreAIC)) print("BEST DESCRYPTED TEXT (IC METHOD): " + text + "\n") print("STECKERS:" + str(steckerinfo)) if steckerscoreGRAM > -1500: print("BINGO GRAM!!! GRAM: " + str(steckerscoreGRAM)) # Trigram score print("BINGO GRAM!!! ORIC: " + str(myic)) # original IC score print("BINGO GRAM!!! BEIC: " + str(steckerscoreIC)) # IC score after first 4 plugs print("BINGO GRAM!!! AFIC: " + str(steckerscoreAIC) + "\n") # IC sore after Trigrams applied print("BEST DESCRYPTED TEXT (GRAM METHOD): " + text) print("STECKERS:" + str(steckerinfo))
def ultimate_MP_method_1_HILLCLIMB(self): #1st step is to find out the plausible walzen and ring settings candidates for next steps using IC strtowrite = "!!! Starting at " + format( datetime.now(), '%H:%M:%S') + " with: " + self.subset[ 0] + "-" + self.subset[1] + "-" + self.subset[2] self.q.put(strtowrite) messagelenght = len(self.ttc) ic = 0 #threshold, everything less than this won't be even evaluated further topic = ic scorer_bi = scorer_ngrams('grams/german_bigrams1941.txt') scorer_tri = scorer_ngrams('grams/german_trigrams1941.txt') scorer_quad = scorer_ngrams('grams/german_trigrams1941.txt') plugs1run = 4 #number of plugs to be indentified by IC plugs2run = 10 - plugs1run #rest of the plugs, identified by trigram score plugboardi = Plugboard() bestoftherunIC = -10000 bestoftherunGRAM = -10000 myscore = -10000 botrstring = "" #-1725 bi1941 #-2900 tri #-4300 quad steckertop = -2900 for r in range(2): reflectori = Reflector("B" if r == 0 else "C") for i in range(26): for j in range(26): for k in range(26): rotors = { 1: Rotor(self.subset[0], 0, i), #slowest, left-most 2: Rotor(self.subset[1], 0, j), #middle 3: Rotor(self.subset[2], 0, k), #fastest, right-most } enigmai = Enigma(rotors, reflectori, plugboardi) text = enigmai.EDcrypt(self.ttc) myic = self.scorer.icscore(text) #myscore = self.scorer_mono.score(text) #in case we'd need monograms (but we don't at this moment) if myic > ic: topic = myic ''' strtowrite = ""+format(datetime.now(), '%H:%M:%S')\ +"\n 1st step Score\n"+str(myic)+"\nGuess: "+text\ +"\nGrunds original: "+str(i)+":"+str(j)+":"+str(k)\ +" Ring3: "+str("0")+" Wheels: "\ +rotor1.number+":"+rotor2.number+":"+rotor3.number\ +" Ref:"+str(reflectori.typ)+"\n" self.q.put(strtowrite) ''' #2nd step is to test right-most and middle rotor combinations for the best scored ones for x in range(26): for y in range(26): #r3shift = 0+y #r2shift = 0 #if rotor2.step>=r3shift: # r2shift = 1 #rotor1 = rotor(self.subset[0], 0,i) #rotor2 = rotor(self.subset[1], x,(abs(j-r2shift-x)%26)) #rotor3 = rotor(self.subset[2], y,((k+r3shift)%26)) rotors = { 1: Rotor(self.subset[0], 0, i), 2: Rotor(self.subset[1], x, j), 3: Rotor(self.subset[2], y, k), } enigmai = Enigma(rotors, reflectori, plugboardi) text = enigmai.EDcrypt(self.ttc) myic = self.scorer.icscore(text) #3rd step is Hill-climbing steckers using trigrams if myic > topic and myic > 0.040: topic = myic ''' strtowrite = ""+format(datetime.now(), '%H:%M:%S')\ +"\n2nd step Score\n"+str(myic)+"\nGuess: "+text\ +"\nGrunds original: "+str(i)+":"+str(j)+":"+str(k)\ +" Ring2: "+str(x)+ " Ring3: "+str(y)+" Wheels: "\ +rotor1.number+":"+rotor2.number+":"+rotor3.number\ +" Ref:"+str(reflectori.typ)+"\n" self.q.put(strtowrite) ''' #bestoftherunIC = topscore #nope #stecker '''strtowrite = ""+format(datetime.now(), '%H:%M:%S') +"\nORIGINAL Score\n"+str(myscore)+"\nGuess: " +text+"\nGrunds original: "+str(i)+":"+str(j)+":"+str(k) +" Grunds new: "+str(i)+":" +str(abs(j-r2shift)%26)+":"+str((k+r3shift)%26) +" Ring3: "+str(o) +" Wheels: "+rotor1.number+":"+rotor2.number+":"+rotor3.number +" Ref:"+str(reflectori.typ)+"\n" #self.q.put(strtowrite) ''' #myscore = self.scorer.score(text) steckerscoreIC, steckerscoreGRAM, steckerscoreAIC, steckerinfo = self.steckerHillClimbTest( rotor1, rotor2, rotor3, reflectori, myic, plugs1run, plugs2run) #strtowrite = "STECKER: "+str(steckerinfo)+"\n\n" #self.q.put(strtowrite) if ((steckerscoreIC > bestoftherunIC and steckerscoreAIC > 0.055) or (steckerscoreGRAM > bestoftherunGRAM and steckerscoreAIC > 0.055)): #print ("CHECKTHISOUT: " +text+"\n") bestoftherunIC = steckerscoreIC bestoftherunGRAM = steckerscoreGRAM strtowrite = "Time "\ +format(datetime.now(), '%H:%M:%S')\ +"\nORIGINAL Score\n"+str(myic)\ +"\nScores\n"+"Original IC:"+str(steckerscoreIC)+"\nAfterwards IC:"+str(steckerscoreAIC)+"\nTrigram:"+str(steckerscoreGRAM)\ +"\nGuess: "+text+"\nGrunds original: "\ +str(i)+":"+str(j)+":"+str(k)+" Grunds new: "\ +"Ring2: "+str(x)+" Ring3: "+str(y)\ +" Wheels: "+rotor1.number+":"+rotor2.number+":"+rotor3.number\ +" Ref:"+str(reflectori.typ)+"\n"\ +"STECKER: "+str(steckerinfo)+"\n\n" self.q.put(strtowrite) if steckerscoreAIC > 0.06: print("BINGO IC!!! " + str(steckerscoreAIC)) print("CHECKTHISOUT: " + text + "\n") if steckerscoreGRAM > -2900: print("CHECKTHISOUT: " + text + "\n") print("BINGO GRAM!!! GRAM:" + str(steckerscoreGRAM) ) # Trigram score print( "BINGO GRAM!!! ORIC:" + str(myic)) # original IC score print( "BINGO GRAM!!! BEIC:" + str(steckerscoreIC) ) # IC score after first 3 plugs print( "BINGO GRAM!!! AFIC:" + str(steckerscoreAIC) + "\n\n" ) # IC sore after Trigrams applied #stecker if bestoftherunIC > -10000: strtowrite = "BOTR: " + str(bestoftherunIC) + "\n" + str( botrstring) strtowrite = "" self.q.put(strtowrite)
def test_Rotor_encode_letter(): A = Rotor('I', 'a') assert A.encode_letter('a')
def ultimate_MP_method_1_INITIAL_EXHAUSTION_EXTENDED_SLOOOW(self): #1st step is to find out the plausible walzen and ring settings candidates for next steps using IC scorer = scorer_ic() #strtowrite = "!!! Starting at " +format(datetime.now(), '%H:%M:%S')+ " with: "+ self.subset[0]+"-"+self.subset[1]+"-"+ self.subset[2] #self.q.put(strtowrite) print("!!! Starting at " + format(datetime.now(), '%H:%M:%S') + " with: " + self.subset[0] + "-" + self.subset[1] + "-" + self.subset[2]) messagelenght = len(self.ttc) bestoftherunIC = -10000 bestoftherunGRAM = -10000 myscore = -10000 botrstring = "" myic = 0 topIC = 0 # initliaze empty enigma for further re-use enigmai = Enigma() c**t = 0 olmajtytajm = 0 for r in range(2): #reflectors B and C enigmai.reflector = Reflector("B" if r == 0 else "C") for i in range(26): for j in range(26): for k in range(26): firstIC = 0 #start = time() rotors = { # i,j,k = rings # l = fastest grund / offset 1: Rotor(self.subset[0], i, 0), #slowest, left-most 2: Rotor(self.subset[1], j, 0), #middle 3: Rotor(self.subset[2], k, 0), #fastest, right-most } enigmai.rotors = rotors text = enigmai.EDcrypt(self.ttc) firstIC = scorer.score(text, messagelenght) topIC = firstIC #test Grunds for fast and middle wheels for l in range(26): for m in range(26): rotors = { # i,j,k = rings # l = fastest grund / offset 1: Rotor(self.subset[0], i, 0), #slowest, left-most 2: Rotor(self.subset[1], j, l), #middle 3: Rotor(self.subset[2], k, m), #fastest, right-most } enigmai.rotors = rotors #print(enigmai) text = enigmai.EDcrypt(self.ttc) secondIC = scorer.score(text, messagelenght) if secondIC > topIC: topIC = secondIC topGrundFast = m topGrundMiddle = l if (topIC > firstIC): strtowrite = str( topIC ) + ";" + rotors[1].number + ";" + rotors[ 2].number + ";" + rotors[3].number + ";" + str( r) + ";" + str(i) + ";" + str( j) + ";" + str(k) + ";" + str( topGrundMiddle) + ";" + str( topGrundFast) self.q.put(strtowrite) else: strtowrite = str( firstIC ) + ";" + rotors[1].number + ";" + rotors[ 2].number + ";" + rotors[3].number + ";" + str( r) + ";" + str(i) + ";" + str( j) + ";" + str(k) + ";0" self.q.put(strtowrite) '''
def test_Rotor_change_setting(): A = Rotor('I', 'a') A.change_setting('b') assert A.window == 'B' assert A.offset == 1