检测英文
在破译密码时可能会有上千个可能的密匙,计算机会因此给出各种各样的结果。那么怎么找出唯一明文呢?如果让计算机先判断结果中是乱码还是英文筛选一遍,再将可能的结果交给我们,会不会比人为翻查上千个结果好很多呢?
判断英文的方法:
我们可以制作一个包含所有英文单词的文本文件(字典文件),通过计算机将解密后的字符串分割成单词(利用空格),在依次查找字典文件中是否有这个单词。通过如此可以判断是单词还是乱码。
当然了,正确解密完成后不可能所有的都是单词,比如“AE86”总不能是单词吧!所以我们需要判断前处理一下字符串将非字母的去掉。剩下的如果大多数是单词则判断为正确的英文。
所需的字典文件:https://pan.baidu.com/s/17FviKC-1amWuOCeZWK-ExA 提取码:wlnp
#detectEnglish.py
UPPERLETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + ' \t\n'
dictionaryFile = open('dictionary.txt')
englishWords = {}
for word in dictionaryFile.read().split('\n'):
englishWords[word] = None
dictionaryFile.close()
return englishWords
ENGLISH_WORDS = loadDictionary()
#返回单词占比
def getEnglishCount(message):
message = message.upper()
message = removeNonLetters(message)
possibleWords = message.split()
if possibleWords == []:
return 0.0
matches = 0
for word in possibleWords:
if word in ENGLISH_WORDS:
matches += 1
return float(matches) / len(possibleWords)
#去除非字母项
def removeNonLetters(message):
lettersOnly = []
for symbol in message:
if symbol in LETTERS_AND_SPACE:
lettersOnly.append(symbol)
return ''.join(lettersOnly)
def isEnglish(message,wordPercentage=20,letterPercentage=85):
wordMatch = getEnglishCount(message) * 100 >= wordPercentage
numLetters = len(removeNonLetters(message))
messageLettersPercentage = float(numLetters) / len(message) * 100
letterMatch = messageLettersPercentage >= letterPercentage
return wordMatch and letterMatch
做一个小测试:
结果为:
在这里removeNonLetters()函数是去除非字母项,如"first1"变为"first";
而getEnglishCount()函数是返回字符串中单词的占比,以便后面isEnglish()函数判断;
isEnglish是通过单词的占比和英文在message中的占比来判断该字符串是否是英文。显然这里的message单词数量超过了20%是正确的。
破译换位加密
知道了如何鉴别是否英文,接下来就能利用计算机轻松的破译了:
所需尝试的密匙也并非无穷大,范围是从1和消息长度之间的整数。利用for循环依次尝试各种密匙下的结果是否满足isEnglish()条件
import detectEnglish,transpositionDecrypt
def main():
myMessage = '''Dtehry ebYo aaoeseOnwdntuvstU’ho ere wRtaiy rieS tnoooyseEw gunw nLoo . nda Frtb b a Y rheCerybOoyetoae.aUn rtntc t lasecioStayb renruln.oa ngdcedurtt sc '''
key,hackedMessage = hackTransposition(myMessage)
if hackedMessage == None:
print('Failed to hack encryption')
else:
print('finally key:%s' %(key))
print(hackedMessage)
def hackTransposition(message):
print('hacking...')
for key in range(1,len(message)):
#print('trying key #%s...' %(key))
decryptedText = transpositionDecrypt.decryptMessage(key,message)
if detectEnglish.isEnglish(decryptedText):
print('possible:')
print('key %s: %s'%(key,decryptedText[:100]))
print()
#判断是否正确,正确则全部显示
print('Enter D for done, or just press Enter to continue hacking...')
response = input('>')
if response.strip().upper().startswith('D'):
return (key,decryptedText)
return None,None #两个被赋值
if __name__ == '__main__':
main()
需要的transpositionDecrypt.py见:https://blog.csdn.net/qq_41853244/article/details/89017492
结果
在这里把可能的结果前100个字符显示让操作者判断是否正确。如果回车则错误继续破译,d则结束破译,显示全部结果:
Don’t worry about what others are doing better than you. Concentrate on beating your own records every day. Success is a battle between YOU and YOURSELF only.(不要担心别人会做得比你好。你只需要每天都做得比前一天好就可以了。成功是一场和自己的比赛。)