Chapter ? - Code Cracker

secret3.py
  1. import secret2 as cipher
  2. #import secret3 as cipher
  3. import cryptoLib
  4. import string, time
  5. def main():
  6.     msg = cryptoLib.getMessage()
  7.     crack(msg)
  8. def getLikelihood(message, key, words):
  9.     testPlaintext = cipher.decrypt(message, key)
  10.         
  11.     realWord = 0
  12.     notRealWord = 0
  13.     for word in testPlaintext.split():
  14.         if word in words:
  15.             realWord += 1
  16.         else:
  17.             notRealWord += 1
  18.         
  19.     return (realWord / float(realWord + notRealWord)) * 100.0
  20. def getWordsFromDictionaryFile():
  21.     # Load the words from the dictionary file.
  22.     dictionaryFile = open('dictionary.txt')
  23.     words = dictionaryFile.readlines()
  24.     dictionaryFile.close()
  25.     
  26.     # Remove the newline character at the end of each word.
  27.     for i in range(len(words)):
  28.         words[i] = words[i].strip()
  29.     
  30.     return words
  31.         
  32. def crack(message):
  33.     maxLikelihood = 0.0
  34.     maxTestKey = 1
  35.     
  36.     words = getWordsFromDictionaryFile()
  37.     
  38.     # Replace any non-letter and non-apostrophe characters with spaces, so
  39.     # that we can match words in the dictionary. Also make all letters
  40.     # lowercase.
  41.     testMessage = ''
  42.     for letter in message:
  43.         if letter not in string.letters and letter != "'":
  44.             testMessage += ' '
  45.         else:
  46.             testMessage += letter.lower()
  47.     
  48.     # Do a test with a few keys to determine how long it will take to
  49.     # go through all of the keys.
  50.     startTime = time.time()
  51.     for i in range(3):
  52.         getLikelihood(testMessage, 1, words)
  53.     endTime = time.time()
  54.     averageTime = (endTime - startTime) / 3.0
  55.     totalTime = averageTime * cipher.MAX_KEY_SIZE
  56.     probableTime = totalTime / 2
  57.     
  58.     print
  59.     print 'Average time to attempt one key: %.1f seconds' % (averageTime)
  60.     print 'Total time to attempt all keys: %.1f seconds' % (totalTime)
  61.     print 'Most likely time to find the key: %.1f seconds' % (probableTime)
  62.     print
  63.         
  64.     
  65.     for testKey in range(1, cipher.MAX_KEY_SIZE + 1):
  66.         print 'Testing key: %s...' % (testKey),
  67.         
  68.         likelihood = getLikelihood(testMessage, testKey, words)
  69.         
  70.         if likelihood > maxLikelihood:
  71.             maxLikelihood = likelihood
  72.             maxTestKey = testKey
  73.             
  74.         print '%.1f%%' % (likelihood)
  75.         
  76.         if likelihood > 95.0:
  77.             break
  78.     
  79.     print 'Most probable key: %s (%.1f%%)' % (maxTestKey, maxLikelihood)
  80.     print 'Decrypted text with this key:'
  81.     print cipher.decrypt(message, maxTestKey)
  82. # TODO: This is an additional function to crack the vigenere cipher
  83. def getKeyFromKeyWord(keyWord):
  84.     key = 0
  85.     for i in range(len(keyWord)):
  86.         #print keyWord[i],
  87.         if keyWord[i] == keyWord[i].upper():
  88.             key += (ord(keyWord[i]) - ord('A')+1) * (52 ** i)
  89.             #print (ord(keyWord[i]) - ord('A')+1) * (52 ** i)
  90.         else:
  91.             key += (ord(keyWord[i]) - ord('a')+1 + 26) * (52 ** i)
  92.             #print (ord(keyWord[i]) - ord('a')+1 + 26) * (52 ** i)
  93.     return key
  94. def getKeyWordFromKey(key):
  95.     pass
  96.         
  97. import sys
  98. if __name__ == '__main__':
  99.     main()
cryptoLib.py
  1. def getMode():
  2.     mode = ''
  3.     while (mode not in 'encrypt e decrypt d'.split()):
  4.         print 'Do you wish to encrypt or decrypt a message?'
  5.         mode = raw_input()
  6.         mode = mode.lower()
  7.         if (mode not in 'encrypt e decrypt d'.split()):
  8.             print 'Enter either "encrypt" or "e" or "decrypt" or "d".'
  9.     return mode
  10. def getMessage():
  11.     print 'Enter your message:'
  12.     message = raw_input()
  13.     
  14.     return message
  15. def getKey(maxKeySize):
  16.     key = 0
  17.     while (not (key >= 1 and key <= maxKeySize)):
  18.         print 'Enter the key number (1-%s)' % (maxKeySize)
  19.         key = int(raw_input())
  20.     return key

Things Covered In This Chapter: