暴力不能解決一切問題

qq_45717538發表於2020-10-19

題解

題目明顯提示暴力方法,盲猜是一個簡單換位密碼,不同於凱撒密碼,每個字母對應的密文是完全混亂的:

abcdefghijklmnopqrstuvwxyz
qwertyuiopasdfghjklzxcvbnm
該演算法是根據每個字母出現的頻率來破解

使用爬坡演算法每次交換兩個字母,計算得分情況,得分越高,正確結果可能性越高
通過四字組確定與文字相似情況

程式碼

import random

import sys
from ngram_score import ngram_score
#引數初始化
text ='XEYREFKMMYZEFWMYHAKTYIXWXKJAPYRINEBIVYUHKXJNPAEUYGZKHYZRNPZATENPZAJANKMJKFLYUMXAAV'
template = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
key = {'A':'A'}
fitness = ngram_score('english_quadgrams.txt')
score = -99e9
maxn = -99e9
j = 0

while 1:
    j +=1
    n=len(template)
    for i in range(n):
        key[template[i]] = chr(ord('A')+i)
    dic = text
    for i in range(len(dic)):
        dic = dic[:i]+key[dic[i]]+dic[i+1:]
    score = fitness.score(dic)
    count = 0
    while count < 1000:
        a = random.randint(0,25)
        b = random.randint(0,25)
        template[a],template[b]= template[b],template[a]
        key[template[a]],key[template[b]] = key[template[b]],key[template[a]]
        dic = text
        for i in range(len(dic)):
            dic = dic[:i]+key[dic[i]]+dic[i+1:]
        sco = fitness.score(dic)
        #此子金鑰代替其對應的父金鑰,提高明文適應度
        if sco > score:
            score = sco
            count = 0
        else:
            template[a],template[b]=template[b],template[a]
            key[template[a]],key[template[b]]=key[template[b]],key[template[a]]
        count = count+1
    if score > maxn:
        maxn = score
        print ('Currrent key: '+''.join(template))
        print ('Iteration total:', j)
        print ('Plaintext: ', dic,maxn)
        sys.stdout.flush()

相關文章