Chapter 21 – Hacking the Vigenère Cipher 331
- for indexes in itertools.product(range(NUM_MOST_FREQ_LETTERS),
repeat=mostLikelyKeyLength):
Create a possible key from the letters in allFreqScores
- possibleKey = ''
- for i in range(mostLikelyKeyLength):
- possibleKey += allFreqScores[i][indexes[i]][0]
- if not SILENT_MODE:
- print('Attempting with key: %s' % (possibleKey))
- decryptedText = vigenereCipher.decryptMessage(possibleKey,
ciphertextUp)
- if detectEnglish.isEnglish(decryptedText):
Set the hacked ciphertext to the original casing.
- origCase = []
- for i in range(len(ciphertext)):
- if ciphertext[i].isupper():
- origCase.append(decryptedText[i].upper())
- else:
- origCase.append(decryptedText[i].lower())
- decryptedText = ''.join(origCase)
Check with user to see if the key has been found.
- print('Possible encryption hack with key %s:' % (possibleKey))
- print(decryptedText[:200]) # only show first 200 characters
- print()
- print('Enter D for done, or just press Enter to continue
hacking:')
- response = input('> ')
- if response.strip().upper().startswith('D'):
- return decryptedText
No English-looking decryption found, so return None.
- return None
- def hackVigenere(ciphertext):
First, we need to do Kasiski Examination to figure out what the
length of the ciphertext's encryption key is.
- allLikelyKeyLengths = kasiskiExamination(ciphertext)
- if not SILENT_MODE:
- keyLengthStr = ''
- for keyLength in allLikelyKeyLengths:
- keyLengthStr += '%s ' % (keyLength)