[Python密码学]--检测英文及破译换位加密

检测英文

在破译密码时可能会有上千个可能的密匙,计算机会因此给出各种各样的结果。那么怎么找出唯一明文呢?如果让计算机先判断结果中是乱码还是英文筛选一遍,再将可能的结果交给我们,会不会比人为翻查上千个结果好很多呢?
判断英文的方法:
我们可以制作一个包含所有英文单词的文本文件(字典文件),通过计算机将解密后的字符串分割成单词(利用空格),在依次查找字典文件中是否有这个单词。通过如此可以判断是单词还是乱码。
当然了,正确解密完成后不可能所有的都是单词,比如“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.(不要担心别人会做得比你好。你只需要每天都做得比前一天好就可以了。成功是一场和自己的比赛。)

猜你喜欢

转载自blog.csdn.net/qq_41853244/article/details/89227983