def bruteForce(self, ciphertext, minReadRate=0.4): """Brute forces all the keys provided by SubClass. minReadRate enforces minimum rate of readable chars""" bestKey = None lowestChi2 = 100000 if self.onlyLowerCase(): ciphertext = ciphertext.lower() for key in self.genKeys(): # genKeys and decrypt are the subclass functions maybePlaintext = self.decrypt(ciphertext,key) if minReadRate > 0.0: readPerc = len([c for c in maybePlaintext if utils.isAlpha(c)]) / len(maybePlaintext) if readPerc < minReadRate: continue chi2 = utils.calcChiSquared(maybePlaintext) if chi2 < lowestChi2: bestKey = key lowestChi2 = chi2 #print(utils.calcTrigraphFitness(self.decrypt(ciphertext, bestKey))) return (bestKey, lowestChi2)
def rot(self, plaintext, shift): ciphertext = '' lowera = ord('a') for c in plaintext: if utils.isAlpha(c): ciphertext += chr(( (ord(c) - lowera + shift) % utils.ALPHABET_SIZE) + lowera) else: ciphertext += c return ciphertext
def encrypt(self, plaintext, key): (a,b) = key ciphertext = '' lowera = ord('a') for c in plaintext: if utils.isAlpha(c): x = ord(c)-lowera y = (a*x+b) % utils.ALPHABET_SIZE ciphertext += chr(lowera+y) else: ciphertext += c return ciphertext
def decrypt(self, ciphertext, key): (a,b) = key plaintext = '' lowera = ord('a') for c in ciphertext: if utils.isAlpha(c): x = ord(c)-lowera y = (utils.multInverse(a, utils.ALPHABET_SIZE)*(x-b)) % utils.ALPHABET_SIZE plaintext += chr(lowera+y) else: plaintext += c return plaintext
def encrypt(self, plaintext, key): ciphertext = '' lowera = ord('a') keylen = len(key) keyIndex = 0 for c in plaintext: if utils.isAlpha(c): shift = ord(key[keyIndex]) - lowera ciphertext += chr(( (ord(c) - lowera + shift) % utils.ALPHABET_SIZE) + lowera) keyIndex = (keyIndex + 1) % keylen # Updating the key else: ciphertext += c # key not updated return ciphertext
def crack(self, ciphertext): keyLen = self.findKeyLength(ciphertext, KEY_LENGTH_UPPER_BOUND) key = '' lowera = ord('a') for i in range( keyLen): # gets each Caesar text embedded in the ciphertext subtext = '' j = i while j < len(ciphertext): c = ciphertext[j] if utils.isAlpha(c): subtext += c j += keyLen lowestShift = 0 lowestChi2 = 100000 for j in range(min(utils.ALPHABET_SIZE, len(ciphertext))): maybePlaintext = self.rot(subtext, j) chi2 = utils.calcChiSquared(maybePlaintext) if chi2 < lowestChi2: lowestShift = j lowestChi2 = chi2 keyShift = 0 if lowestShift != 0: keyShift = 26 - lowestShift # We found the amount to shift for decryption, now we want the encryption key key += chr(keyShift + lowera) key = self.refineKey(key) plaintext = self.decrypt(ciphertext, key) chi2 = utils.calcChiSquared(plaintext) return (key, chi2)
def token_recognition(token, digitDFA, charDFA, stringDFA, commentDFA, o_H_DFA, line_number, character_table, token_l, error_l): #关键字和标识符 if isAlpha(token[0]): if token in keywords: # print(token + "\t<关键字\t" + token + ">\t" + str(line_number)) # if token + "\t关键字\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t关键字\t" + token + "\t" + str(line_number)) else: if token not in character_table: character_table.append(token) # print(token + "\t<标识符\t" + token + ">\t" + str(line_number)) if token + "\t标识符\t" + token + "\t" + str( line_number) not in token_l: token_l.append(token + "\t标识符\t" + token + "\t" + str(line_number)) if isOp(token[0]): # print(token + "\t<运算符\t" + token + ">\t" + str(line_number)) #if token + "\t运算符\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t运算符\t" + token + "\t" + str(line_number)) if isDigit(token[0]): digitDFA_result, isfloat = digitDFA.in_digitDFA(token) if digitDFA_result: if isfloat: # print(token + "\t<浮点型常量\t" + token + ">\t" + str(line_number)) #if token + "\t浮点型常量\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t浮点型常量\t" + token + "\t" + str(line_number)) else: # print(token + "\t整形常量\t" + token + "\t" + str(line_number)) #if token + "\t整形常量\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t整形常量\t" + token + "\t" + str(line_number)) o_H_DFA_result, error_message, is_octal = o_H_DFA.in_O_H_DFA(token) if o_H_DFA_result: if is_octal: # print(token + "\t<八进制常量\t" + token+ ">\t" + str(line_number)) #if token + "\t八进制常量\t" + token+ "\t" + str(line_number) not in token_l: token_l.append(token + "\t八进制常量\t" + token + "\t" + str(line_number)) else: # print(token + "\t<十六进制常量\t" + token + ">\t" + str(line_number)) #if token + "\t十六进制常量\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t十六进制常量\t" + token + "\t" + str(line_number)) if not digitDFA_result and not o_H_DFA_result: # print("错误:在" + str(line_number) + "行, 试图将" + token + "解析为数字型常量发生错误!") #if "错误:在" + str(line_number) + "行, 试图将" + token + "解析为数字型常量发生错误!" not in error_l: error_l.append("错误:在" + str(line_number) + "行, 试图将" + token + "解析为数字型常量发生错误!") if isChar(token[0]): charDFA_result, error_message = charDFA.in_charDFA(token) if charDFA_result: # print(token + "\t<字符型常量\t" + token + ">\t" + str(line_number)) #if token + "\t字符型常量\t" + token + "\t" + str(line_number) not in error_l: token_l.append(token + "\t字符型常量\t" + token + "\t" + str(line_number)) else: # print("错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符型常量发生错误!" ) #if "错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符型常量发生错误!" not in error_l: error_l.append("错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符型常量发生错误!") if isString(token[0]): stringDFA_result, error_message = stringDFA.in_stringDFA(token) if stringDFA_result: # print(token + "\t<字符串常量\t" + token + ">\t" + str(line_number)) #if token + "\t字符串常量\t" + token + "\t" + str(line_number) not in token_l: token_l.append(token + "\t字符串常量\t" + token + "\t" + str(line_number)) else: # print("错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符串常量发生错误!") #if "错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符型常量发生错误!" not in error_l: error_l.append("错误:在" + str(line_number) + "行, 试图将" + token + "解析为字符型常量发生错误!") return character_table, token_l, error_l