print "\nAnalyzing message number %d: %s\n" % (msgNum+1, msg) print "Message IC: %.4f" % msgIC print "Message is likely %s\n" % ("polyalphabetic" if isPoly else "monoalphabetic") # 3. For the ones which you suspect aren't monoalphabetic, they have been encrypted either using a Vignere cipher or Hills system. In order to differentiate, we shall apply the standard Vignere tests for keyword - the messages have specifically been chosen so that a Hills system message will be recognizable by how these tests perform. if isPoly: # (a) Find all repeated strings of lengths 3 or more and apply the Kasiski test. kt = KasiskiTest() kasiskiFailed = False repeatedSubstrs = kt.getRepeatedSubstrs(msg, 3) if repeatedSubstrs: print "Repeated substrs of length >= 3:\n%s\n" % repeatedSubstrs print "Potential keys determined by running Kasiski test on each substring:" # print out potential key lengths for every substring for keyLens in kt.getAllPotentialKeyLens(msg, repeatedSubstrs): print keyLens mostLikelyKeysKasiski = kt.getMostLikelyKeyLens(msg, repeatedSubstrs) print "\nMost likely key lengths using Kasiski test:\n%s\n" % (mostLikelyKeysKasiski) # initialize the letter frequency class letFreq = LetterFrequency() # loop through the top 4 most likely key lengths according to the kasiski test for keyLen in mostLikelyKeysKasiski[:2]: # Split the message into keyLen columns msgColumns = polyCi.msgSplit(msg, keyLen) # holds the potential keyword keyword = "" # perform frequency analysis on each column