from operator import itemgetter class Substitution: def __init__(self,filename = "text.txt"): self.filename = filename self.getText() self.setAlphabet() self.setStandardPermutation() self.findInversePermutation() self.suggestedPermutation = {} def cryptAnalysis(self): self.countLetters() self.setDigrams() self.setTrigrams() self.digramCount = self.countPhrase(self.digrams) self.trigramCount = self.countPhrase(self.trigrams) self.printCount() self.printDigramCount() self.printTrigramCount() def getText(self): result_f = open(self.filename) self.inputText = "" for line in result_f: self.inputText = self.inputText + line.strip("\n") self.inputText.upper() def setAlphabet(self): self.alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] def setStandardPermutation(self): self.permutation = {'A':'D', 'B':'G','C':'T', 'D':'E', 'E':'F', 'F':'H' , 'G':'Q', 'H':'P', 'I':'U', 'J':'A', 'K':'W', 'L':'I', 'M':'Z', 'N':'C', 'O':'X', 'P':'B', 'Q':'N', 'R':'S', 'S':'O', 'T':'R', 'U':'V', 'V':'K', 'W':'J', 'X':'L', 'Y':'M', 'Z':'Y'} def setPermutation(self,permutation): if len(permutation) == 26: temp = self.permutation self.permutation = permutation self.findInversePermutation() if unlegalPerm: self.permutation = temp self.findInversePermutation() else: print "Need to have permutation of length 26" def findInversePermutation(self): self.iversePermutation = {} self.unlegalPerm = False for key,value in self.permutation: if(value in self.inversePermutation.keys()): print "Not a legal permutation" self.unlegalPerm = True else: self.inversePermutation[value] = key def setDigrams(self): self.digrams = [] for i in range((len(self.inputText)-2)): self.digrams.append(self.inputText[i:(i+2)]) def setTrigrams(self): self.trigrams = [] for i in range((len(self.inputText)-3)): self.trigrams.append(self.inputText[i:(i+3)]) # number of instances of a letter or small phrase (th, the, etc...) in a text def numberOfInstances(self,text, phrase): instances = 0 length = len(text)-len(phrase) # to not end up outside array for i in range(length): if(text[i:(i+len(phrase))]) == phrase: instances = instances + 1 return instances def countLetters(self): self.countTable = {} for letter in self.alphabet: self.countTable[letter] = self.numberOfInstances(self.inputText,letter) def countPhrase(self,phrases): phraseCount = {} for phrase in phrases: phraseCount[phrase] = self.numberOfInstances(self.inputText,phrase) return phraseCount # Find the howMany highest numbers in the list theList (unclear if needed) def highestNumbers(self,theList = {}, howMany = 0): result = [] result.insert(0,[-1,-1]) for key in theList: if not (len(result) == 0): i = 0 while i) Where filename is name of the file containing either the message or ciphertext you want to work with. If no input is given, text.txt will be used. Note that a file with the given filename input as name must sit in the same directory as the substitution.py file. It contains the following methods: cryptAnalysis(): Makes a count of each letter, each digram and each trigram and prints the result. addletter(from,to): Add to the permutation we are building as suggestion for which permutation was used. removeletter(from): Removes the the (from,to) tuple from the permutation we are building. encrypt(): Encrypts the message from with the pre set permutation. decrypt(): Decrypts the ciphertext from with the permutation we are building, i.e. gives partial decryption if not the whole permutation is set. showcipher(): Prints out the ciphertext in fulldecrypt(): Uses the inverse of the preset permutation to decrypt. Note that the pre set permutation is not the one you are building with addletter(from,to) and removeletter(from) setPermutation(permutation): Redefines the pre set permutation. Must be a full valid permutation (all 26 characters) Example cs = Substitution() cs.cryptAnalysis() cs.addletter(from,to) cs.removeletter(from) cs.decrypt() cs.encrypt() cs.showcipher() """