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 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_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_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 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_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 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_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 __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 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'
class Enigma(): ''' This class will bring together components to create an actual Enigma machine. Thought about geometrically, the Enigma can be viewed as follows: Keyboard -> Plugboard -> L Rotor -> M Rotor -> R Rotor -> Reflector. The generic initial rotor ordering (which can be changed by the user) is L = I, M = II, R = III (I,II,III are the three Wehrmacht Enigma rotors defined in components.py) ''' 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 __repr__(self): print('Keyboard <-> Plugboard <-> Rotor ' + self.rotor_order[0] + ' <-> Rotor ' + self.rotor_order[1] + ' <-> Rotor ' + self.rotor_order[2] + ' <-> Reflector ') return 'Key: ' + self.key def encipher(self, message): """ Given a message string, encode or decode that message. """ cipher = '' # Test the message string to make sure it only contains a-zA-Z if bool(re.compile(r'[^a-zA-Z ]').search(message)): return 'Please provide a string containing only the characters a-zA-Z and spaces.' for letter in message.upper().replace(" ", "").strip(): cipher += self.encode_decode_letter(letter) return cipher def decipher(self, message): """ Encryption == decryption. """ return self.encipher(message) def encode_decode_letter(self, letter): """ Takes a letter as input, steps rotors accordingly, and returns letter output. Because Enigma is symmetrical, this works the same whether you encode or decode. """ # Make sure the letter is in a-zA-Z. if bool(re.compile(r'[^a-zA-Z ]').search(letter)): return 'Please provide a letter in a-zA-Z.' # First, go through plugboard. if letter in self.plugboard.swaps: letter = self.plugboard.swaps[letter.upper()] # Next, step the rotors. self.l_rotor.step() # Send the letter through the rotors to the reflector. # Get the index of the letter that emerges from the rotor. left_pass = self.l_rotor.encode_letter(ALPHABET.index(letter.upper())) # Must match letter INDEX, not letter name to reflector as before. refl_output = self.reflector.wiring[ALPHABET[(left_pass) % 26]] # Send the reflected letter back through the rotors. final_letter = ALPHABET[self.r_rotor.encode_letter( ALPHABET.index(refl_output), forward=False)] if final_letter in self.plugboard.swaps: return self.plugboard.swaps[final_letter] else: return final_letter def set_rotor_position(self, position_key, printIt=False): ''' Updates the visible window settings of the Enigma machine, rotating the rotors. The syntax for the rotor position key is three letter string of the form 'AAA' or 'ZEK'. ''' if type(position_key) == str and len(position_key) == 3: self.key = position_key self.l_rotor.change_setting(self.key[0]) self.m_rotor.change_setting(self.key[1]) self.r_rotor.change_setting(self.key[2]) if printIt: print('Rotor position successfully updated. Now using ' + self.key + '.') else: print('Please provide a three letter position key such as AAA.') def set_rotor_order(self, 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.r_rotor = Rotor(order[2], self.key[2]) self.m_rotor = Rotor(order[1], self.key[1], self.r_rotor) self.l_rotor = Rotor(order[0], self.key[0], self.m_rotor) # 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 set_plugs(self, swaps, replace=False): ''' Update the plugboard settings. Swaps takes the form ['AB', 'CD']. If replace is true, then this method will erase the current plugboard settings and replace them with new ones. ''' self.plugboard.update_swaps(swaps, replace)
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