多表古典密码统计分析之Vigenere算法保姆级教学(含Kasiski测试法和重合指数法)
?該算法參考于現代密碼學第二版2.3.2多表古典密碼統計分析
由于書上內容的介紹難以理解,下面我將把我個人對Kasiski測試法和重合指數法這兩種方法的理解用文字和代碼表示
參考文章
維吉尼亞密碼的破解算法及python代碼實現_Vio1let的博客-CSDN博客
1.首先,需要一篇明文用采用Vigenere來加密?
下面我將以課本給出的例子為例進行運算
課本明文(密文3)為(這里除去了標點符號和全部大寫):THEALMONDTREEWASINTENTATIVEBLOSSOMTHEDAYSWERELONGEROFTENENDINGWITHMAGNIFICENTEVENINGSOFCORRUGATEDPINKSKIESTHEHUNTINGSEASONWASOVERWITHHOUNDSANDGUNSPUTAWAYFORSIXMONTHSTHEVINEYARDSWEREBUSYAGAINASTHEWELLORGANIZEDFARMERSTREATEDTHEIRVINESANDTHEMORELACKADAISICALNEIGHBORSHURRIEDTODOTHEPRUNINGTHEYSHOULDHAVEDONEINNOVEMBER?
將明文以Vigenere的加密方式變為密文?
此處密鑰為:janet
import operator fo=open("明文3.txt","r") fname=fo.readlines() fo.close() str="".join(fname) zfc="" for i in str:if 64<ord(i.upper())<92:zfc+=ielse:continue d={} for i in zfc:if i in d:d[i] += 1else:d[i] = 1 d = sorted(d.items(), key=operator.itemgetter(1), reverse=True) print("明文詞頻統計:",d) result=[] jg=[] zz=[] for i in zfc:j=i.upper()t=ord(j)-65result.append(t) x=input("請輸入密鑰:") for i in x:m = ord(i.upper()) - 65jg.append(m) m = len(result) n = len(jg) k = m // n + 1 jg = jg * k result = [(x + y) % 26 for x, y in zip(result, jg)] for i in result:t = chr(i + 65)zz.append(t) fname2 = open("密文3.txt", "w+") fname2.writelines(zz) fname2.close() str="".join(zz) dict={} for j in str:if j in dict:dict[j] += 1else:dict[j] = 1 dict = sorted(dict.items(), key=operator.itemgetter(1), reverse=True) print("密文詞頻統計:",dict)密文3:CHREEVOAHMAERATBIAXXWTNXBEEOPHBSBQMQEQERBWRVXUOAKXAOSXXWEAHBWGJMMQMNKGRFVGXWTRZXWIAKLXFPSKAUTEMNDCMGTSXMXBTUIADNGMGPSRELXNJELXVRVPRTULHDNQWTWDTYGBPHXTFALJHASVBFXNGLLCHRZBWELEKMSJIKNBHWRJGNMGJSGLXFEYPHAGNRBIEQJTAMRVLCRREMNDGLXRRIMGNSNRWCHRQHAEYEVTAQEBBIPEEWEVKAKOEWADREMXMTBHHCHRTKDNVRZCHRCLQOHPWQAIIWXNRMGWOIIFKEE
2.Kasiski測試法推斷密鑰長度
Kasiski測試法:密文中出現兩個相同字母組,它們所對應的明文字母相同的可能性很大,這樣的兩個密文字母組之間的距離可能為密鑰長度的整數倍。(注意:相同的字母組長度最少為3)
在該段密碼中我選取字符長度為3的進行測試
def miyao_length(cipher):jh=[]d={}b=[]wz=0for i in range(len(cipher)-2):#遍歷整個密文str = cipher[i:i+3]jh.append(str)#把整個密文按照三分字符進行統計for j in jh:#統計三個字符的相同字符組出現的次數if j in d:d[j]+=1else:d[j]=1max_list=[]max_value =max(d.values())#得到最多出現字符的次數為5for m, n in d.items():if n == max_value:max_list.append(m)#把出現最多次的所有字符串找到CHRfor i in max_list:a = [m.start() for m in re.finditer(i,cipher)]#查找這些字符的位置[0,165,235,175,285]s = []if a[0]==0:del a[0]#如果這個字符出現在最前面,則后面字符出現的位置即距離for j in range(2, a[0] + 1):#這個密鑰長度只有可能是165除1以外的因子if a[0] % j == 0:s.append(j)#[5,15,165]for n in s:num = 0for k in a[1:len(a)]:#找出[165,235,175,285]公因子if k % n == 0:num += 1if num == len(a)-1:num = nb.append((i,num))#以元組的形式保存('CHR',5)if len(b)!=0:print("根據密文中子串%s的位置推斷密鑰長度最有可能為:%d" % (max(b)))else:print("在三個字符的字符串中未有滿足條件的字符串!")3.計算重合指數MIC,分組進一步確認密鑰長度
假設密鑰長度在10以內,進行分組;
當密鑰長度為5,則
第一組:CVABWEBQBUAWWQRWWXANTBDPXXRDWBFAXCWMNJJFAIACNRNCATBWKDMCDCQQXWK
第二組:HOEITESEWOOEGMFTIFUDSTNSNVTNDPASNHESBGSEGEMRDRSHEAIEORTHNHOANOE
第三組:RARANOBQRASAJNVRAPTCXUGRJRUQTHLVGRLJHNGYNQRRGINRYQPVEEBRVRHIRIE
第四組:EHAXXPQEVKXHMKGZKSEMMIMEEVLWYXJBLZEIWMLPRJVELMRQEEEKWMHTRCPIMI
第五組:EMTXBHMRXXXBMGXXLKMGXAGLLPHTGTHFLBKKRGXHBTLMXGWHVBEAAXHKZLWWGF
重合指數即第一組出現字母'A'的次數乘以(字母'A'的次數-1)/第一組的長度乘以(第一組的長度-1),一直到字母z的求和,其他四組也進行這樣的運算,最后全部加起來求平均值得出來的MIC即稱為密鑰長度為5的重合指數
此時,得到9個密鑰長度的平均重合指數,進行判斷看哪個MIC值最接近0.065,如果密文的重合指數非常接近0.065,那么說明它使用了單表替換;如果兩段密文的重合指數相似,那么說明它們使用了同一種代換加密方式,即使用同一密鑰進行加密。
def countMIC(t):d = {}for i in t:#統計改組每個字母出現的次數if i in d:d[i] += 1else:d[i] = 1dict = sorted(d.items(), key=operator.itemgetter(1), reverse=True)#按照出現的次數從大到小排序sum = 0result=[]for i in range(len(dict)):#計算重合指數sum += dict[i][1] * (dict[i][1] - 1)return sum/(len(t)*(len(t)-1)) def miyao_len(cipher):fg = list(cipher)miyaosum=[]for i in range(1, 10):#假設密鑰長度在10以內,可以改num=0for j in range(i):t = fg[j::i]#根據密鑰長度分組MIC=countMIC(t)#計算重合指數的函數num+=MIC#求和以便求平均值if j+1==i:print("密鑰長度為{}時,平均重合指數為{:.5f}".format(i,num/i))miyaosum.append(round((num/i),6))figure_MIC(miyaosum)min=1for i in range(len(miyaosum)):#判斷9種密鑰長度哪個最接近0.065if abs(miyaosum[i]-0.065)<min:min=abs(miyaosum[i]-0.065)n=i+1print("根據重合指數進一步證實密鑰長度為:{}".format(n))return n4.確定密鑰長度為5后,計算各組之間的交互重合指數
交互重合指數:先分組同上,交互即計算第i組和第j組一直第五組,其中j>i,那么一共就是有10組;
重合指數即計算第一組中字母'A'出現的概率*第二組偏移n以后'A'出現的概率一直到字母'Z' 求和,出現26個交互重合指數即偏移量可能為的26個字母,偏移量即第一組保持不變,第二組所有字母往后偏移0~25位,在偏移后會得到新的字母'A'的概率,所以會得到26個不一樣的交互重合指數;
| i | j | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 26個交互重合指數 |
| 1 | 2 | 0.028 0.027 0.028 0.034 0.039 0.037 0.026 0.025 0.052 0.068 0.044 0.026 0.037 0.043 0.037 0.043 0.037 0.028 0.041 0.041 0.034 0.037 0.051 0.045 0.042 0.036 |
| 1 | 3 | 0.039 0.033 0.040 0.034 0.028 0.053 0.048 0.033 0.029 0.056 0.050 0.045 0.039 0.040 0.036 0.037 0.032 0.027 0.037 0.036 0.031 0.037 0.055 0.029 0.024 0.037 |
| 1 | 4 | 0.034 0.043 0.025 0.027 0.038 0.049 0.040 0.032 0.029 0.034 0.039 0.044 0.044 0.034 0.039 0.045 0.044 0.037 0.055 0.047 0.032 0.027 0.039 0.037 0.039 0.035 |
| 1 | 5 | 0.043 0.033 0.028 0.046 0.043 0.044 0.039 0.031 0.026 0.030 0.036 0.040 0.041 0.024 0.019 0.048 0.070 0.044 0.028 0.038 0.044 0.043 0.047 0.033 0.026 0.046 |
| 2 | 3 | 0.046 0.048 0.041 0.032 0.036 0.035 0.036 0.030 0.024 0.039 0.034 0.029 0.040 0.067 0.041 0.033 0.037 0.045 0.033 0.033 0.027 0.033 0.045 0.052 0.042 0.030 |
| 2 | 4 | 0.046 0.034 0.043 0.044 0.034 0.031 0.040 0.045 0.040 0.048 0.044 0.033 0.024 0.028 0.042 0.039 0.026 0.034 0.050 0.035 0.032 0.040 0.056 0.043 0.028 0.028 |
| 2 | 5 | 0.033 0.033 0.036 0.046 0.026 0.018 0.043 0.080 0.050 0.029 0.031 0.045 0.039 0.037 0.027 0.026 0.031 0.039 0.040 0.037 0.041 0.046 0.045 0.043 0.035 0.030 |
| 3 | 4 | 0.038 0.036 0.040 0.033 0.036 0.060 0.035 0.041 0.029 0.058 0.035 0.035 0.034 0.053 0.030 0.032 0.035 0.036 0.036 0.028 0.046 0.032 0.051 0.032 0.034 0.030 |
| 3 | 5 | 0.035 0.034 0.034 0.036 0.030 0.043 0.043 0.050 0.025 0.041 0.051 0.050 0.035 0.032 0.033 0.033 0.052 0.031 0.027 0.030 0.072 0.035 0.034 0.032 0.043 0.027 |
| 4 | 5 | 0.052 0.038 0.033 0.038 0.041 0.043 0.037 0.048 0.028 0.028 0.036 0.061 0.033 0.033 0.032 0.052 0.034 0.027 0.039 0.043 0.033 0.027 0.030 0.039 0.048 0.035 |
?5.計算方程式確定密鑰之間的關系
根據偏移量可得各個密鑰之間的關系:
k1-k2=9
k1-k5=16
k2-k3=13
k2-k5=7
k3-k5=20
k4-k5=11
根據上式可得各個密鑰間的關系為 [k1, k1 + 17, k1 + 4, k1 + 21, k1 + 10]
def contact(k,i,j,miyao):k1, k2, k3, k4, k5, k6, k7, k8, k9 = sympy.symbols("k1 k2 k3 k4 k5 k6 k7 k8 k9")#因為假設密鑰長度在10以內daishu=[k1,k2,k3,k4,k5,k6,k7,k8,k9]ds=daishu[0:miyao]#取前五位[k1,k2,k3,k4,k5]MIC_ij = []sz=[]print("根據偏移量可得各個密鑰之間的關系:")for x,y,z in zip(i,j,k):t = 0if ds[x-1]==0:ds[x - 1]=k1print("%s-%s=%d"%(ds[x-1],ds[y-1],z))#將式子展示出來 #由于解方程是4個式子解四個未知數,所以要對式子進行篩選if ds[x-1]==k1:#必定有k1,方便賦值k1=0MIC_ij.append(ds[x - 1])if ds[x-1] not in MIC_ij and ds[y-1] in MIC_ij:#式子必須只有一個未知數,才可以解方程t=1MIC_ij.append(ds[x-1])if ds[x-1] in MIC_ij and ds[y-1] not in MIC_ij:t = 1MIC_ij.append(ds[y- 1])if t==1:if ds[x-1]==k1:ds[x - 1]=0sz.append(ds[x - 1]-ds[y-1]-z)#結果篩選后的式子del ds[0]a = sympy.solve(sz,ds)#{k2: -9, k3: -22, k4: -5, k5: -16}gx=[]for m,n in a.items():gx.append(n)gx.insert(0,0)gx=[(26+i)%26 for i in gx]gxs=[i+k1 for i in gx]#[k1, k1 + 17, k1 + 4, k1 + 21, k1 + 10]print("根據上式可得各個密鑰間的關系為",gxs)return gx5.確定密鑰,同時解密明文
?有了密鑰之間的關系,就可以得到26個密鑰,其中25個都是偽密鑰,我通過單表古典密碼26個英文字母出現頻率統計分析圖進行判斷唯一的真密鑰
| 子母 | 頻率 | 字母 | 頻率 |
| A | 0.082 | N | 0.067 |
| B | 0.015 | O | 0.075 |
| C | 0.028 | P | 0.019 |
| D | 0.043 | Q | 0.001 |
| E | 0.127 | R | 0.060 |
| F | 0.022 | S | 0.063 |
| G | 0.020 | T | 0.091 |
| H | 0.061 | U | 0.028 |
| I | 0.070 | V | 0.010 |
| J | 0.002 | W | 0.023 |
| K | 0.008 | X | 0.001 |
| L | 0.040 | Y | 0.020 |
| M | 0.024 | Z | 0.001 |
?根據該表不難發現字母E的頻率最高且相較于其他25個字母高太多了,所以只需要判斷解密后明文的26個字母中出現頻率最高的是字母E即可(當然這種方法不絕對保證)
def certain_miyao(k,cipher,miyaolen):for i in range(26):t=[(i+j)%26 for j in k]#遍歷26個密鑰k1 = t * (len(cipher)// miyaolen + 1)k1=[chr((ord(i)-65-j)%26+65) for i,j in zip(cipher,k1)]d = {}for j in k1:if j in d:d[j] += 1else:d[j] = 1dict = sorted(d.items(), key=operator.itemgetter(1), reverse=True)k1="".join(k1)if dict[0][0]=='E':print("由單表古典密碼統計分析出現的字母頻率判斷可知:")t=[chr(i+65) for i in t]word = wordninja.split(k1)#根據得出來的明文字符串按單詞進行分割plain = ''for i in range(len(word)):plain += word[i]plain += ' '#得到可以看得懂的明文print("當密鑰為%s時,明文為%s"%(t,plain))密文:
cbkznkiyjsrofgnqadnzuqigscvxizgsjwucusrdkxuahgzrhywtvdjeiuwsrrtnpszbvpzncngztbvsrnzuqigscvfjwqgjwcytwdazuqigscvfjwqgjwjhkfdylmcbmhonbmbvdnvbmwbnacjaphhonbmbvdnvbmwbnaublsbdnjjneoroyfmxfhixpzpcozzuqigscvxcvhdmfgxmgovzsqmvzyvwyzmsczoajsejifoakdcrehwhgdehvmtnmvvmesvzifutzfjzoalwqztunwvdvmfhesvzifutzfjzoalwqztunpsnoyfleoxdetbwfsoyfjmfhjuxuagnarsfqydoyfjzsrzeujmfhjuubihrjdfinwsnepcawdnkbobvnmzucmghijjmbscjejnapddehlmqddmfxncqbfpxwfejifpqzhikiyaiozimubwuzufazsdjwdiudzmztivcmgp
密鑰:uiozvrb(長度為7)
明文:
??It was the best of times.It was the worst of times. It was the age of wisdom. It was the age offoolishness. It was the epoch of belief. It was the epoch of incredulity. It was the season of light. It was the season of darkness. It was the spring of hope. It was the winter of despair.We had everything before us. We had nothing before us. We were all going direct to heaven. We were all going direct the other way. In short, the period was so, far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.
密文:
krkpekmcwxtvknugcmkxfwmgmjvpttuflihcumgxafsdajfupgzzmjlkyykxdvccyqiwdncebwhyjmgkazybtdfsitncwdnolqiacmchnhwcgxfzlwtxzlvgqecllhimbnudynagrttgiiycmvyyimjzqaxvkcgkgrawxupmjwqemiptzrtmqdciakjudnnuadfrimbbuvyaeqwshtpuyqhxvyaeffldmtvrjkpllsxtrlnvkiajfukycvgjgibubldppkfpmkkuplafslaqycaigushmqxcityrwukqdftkgrlstncudnnuzteqjrxyafshaqljsljfunhwiqtehncpkgxspkfvbstarlsgkxfibffldmerptrqlygxpfrwxtvbdgqkztmtfsqegumcfararhwerchvygczyzjaacgntgvfktmjvlpmkflpecjqtfdcclbncqwhycccbgeanyciclxncrwxofqieqmcshhdccughsxxvzdnhwtycmcbcrttvmurqlphxnwddkopqtehzapgpfrlkkkcpgadmgxdlrchvygczkerwxyfpawefsawukmefgkmpwqicnhwlnihvycsxckf
密鑰: crypt (長度為5)
明文:
??I am alive here, my beloved, for the reason to adore you. Oh!How anxious I have been for you and how sorry I am about all you must have suffered in having no news from us. May heaven grant that this letter reaches you. Do not write to me, this would compromise all of us and above all,do not return under any circumstances. It is known that it was you who helped us to get away from here and all would be lost if you should show yourself.We are guarded day and night. I do not care you are not here. Do not be troubled on my account. Nothing will happen to me. The national assemble will show leniency. Farewell the most loved of men. Be quiet if you can take care of yourself.For myself I cannot write any more, but nothing in the world could stop me to adore you up to the death.
附上兩篇測試文章
最后代碼如下:?
import operator import wordninja#英語里的結巴庫 import re#正則表達式 import matplotlib.pyplot as plt#畫圖 from prettytable import PrettyTable#畫表 import sympy def alpha(cipher): # 預處理,去掉空格以及回車c = ''for i in range(len(cipher)):if (cipher[i].isalpha()):c += cipher[i]print("密文的長度為%d"%len(c))return c def figure(cipher):zfc=list(cipher)d={"A":0,"B":0,"C":0,"D":0,"E":0,"F":0,"G":0,"H":0,"I":0,"J":0,"K":0,"L":0,"M":0,"N":0,"O":0,"P":0,"Q":0,"R":0,"S":0,"T":0,"U":0,"V":0,"W":0,"X":0,"Y":0,"Z":0}for i in zfc:if i in d:d[i] += 1else:d[i] = 1d = sorted(d.items(), reverse=False)zm = [i[0] for i in d]sz = [round(i[1] / len(cipher), 4) for i in d]plt.rcParams['font.sans-serif'] = ['SimHei']plt.title('密文頻率統計分析圖')plt.xlabel('字母')plt.ylabel('頻率')plt.plot(zm, sz, 'or-')plt.show() def miyao_length(cipher):jh=[]d={}b=[]wz=0for i in range(len(cipher)-2):str = cipher[i:i+3]jh.append(str)#把整個密文按照三分字符進行統計for j in jh:if j in d:d[j]+=1else:d[j]=1max_list=[]max_value =max(d.values())#求出最多的三個字符的個數(有多個這樣的字符)for m, n in d.items():if n == max_value:max_list.append(m)#把最多的字符找到for i in max_list:a = [m.start() for m in re.finditer(i,cipher)]#查找這些字符的位置s = []if a[0]==0:del a[0]for j in range(2, a[0] + 1):if a[0] % j == 0:s.append(j)for n in s:num = 0for k in a[1:len(a)]:if k % n == 0:num += 1if num == len(a)-1:num = nb.append((i,num))if len(b)!=0:print("根據密文中子串%s的位置推斷密鑰長度最有可能為:%d" % (max(b)))else:print("在三個字符的字符串中未有滿足條件的字符串!") def figure_MIC(t):x=[i+1 for i in range(len(t))]plt.rcParams['font.sans-serif'] = ['SimHei']plt.title('各密鑰長度的平均交互重合指數')plt.xlabel('密鑰長度')plt.ylabel('平均交互重合指數')plt.plot(x,t, 'or-')plt.show() def countMIC(t):d = {}for i in t:if i in d:d[i] += 1else:d[i] = 1dict = sorted(d.items(), key=operator.itemgetter(1), reverse=True)sum = 0result=[]for i in range(len(dict)):sum += dict[i][1] * (dict[i][1] - 1)return sum/(len(t)*(len(t)-1)) def miyao_len(cipher):fg = list(cipher)miyaosum=[]for i in range(1, 10):num=0for j in range(i):t = fg[j::i]MIC=countMIC(t)num+=MICif j+1==i:print("密鑰長度為{}時,平均重合指數為{:.5f}".format(i,num/i))miyaosum.append(round((num/i),6))figure_MIC(miyaosum)min=1for i in range(len(miyaosum)):if abs(miyaosum[i]-0.065)<min:min=abs(miyaosum[i]-0.065)n=i+1print("根據重合指數進一步證實密鑰長度為:{}".format(n))return n def figure_len(t,cipher):zf=list(cipher)sum=[]for i in range(t):fg=zf[i::t]d = {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "G": 0, "H": 0, "I": 0, "J": 0, "K": 0, "L": 0, "M": 0,"N": 0,"O": 0, "P": 0, "Q": 0, "R": 0, "S": 0, "T": 0, "U": 0, "V": 0, "W": 0, "X": 0, "Y": 0, "Z": 0}for i in fg:if i in d:d[i] += 1else:d[i] = 1d = sorted(d.items(), reverse=False)sz = [round(i[1] / len(cipher), 4) for i in d]sum.append(sz)x = [chr(i + 65) for i in range(26)]plt.rcParams['font.sans-serif'] = ['SimHei']plt.title('分組后的頻率統計分析圖')plt.xlabel('字母')plt.ylabel('頻率')ys=['ob-','vg--','sr-.','^c:','+m-','ok--','+r:','^k-.','sc*']tl=["第一組", "第二組", "第三組", "第四組", "第五組", "第六組", "第七組",'第八組','第九組']for j in range(len(sum)):plt.plot(x, sum[j],ys[j])plt.legend(tl[0:len(sum)],loc="upper right")plt.show() def count_group_MIC(group1,group2,n):MIC=0count_1 = [0 for i in range(26)] # [26個0]count_2 = [0 for i in range(26)]for j in range(len(group1)):count_1[ord(group1[j]) - ord('A')] += 1for i in range(len(group2)):count_2[(ord(group2[i]) - ord('A')+n)%26] += 1for i in range(26):MIC += count_1[i] * count_2[i] / (len(group1) *len(group2))return int(MIC*pow(10,3))/1000 def figure_k(pyl_k,lenmiyao):x = PrettyTable(["i", "j", "密文子串的交互重合指數MIC"])t=int(len(pyl_k)/26)for n in range(2,t):if n*(n-1)==2*t:num=nbreakn=1m = 1for i in range(int(len(pyl_k)/26)):if n<num:n += 1else:m=m+1n=m+1siwei = []for k in pyl_k[i*26:(i+1)*26]:k=f"{k:.3f}"siwei.append(k)t=''.join(str(x) for x in siwei)pattern = re.compile('.{5}')result=' '.join(pattern.findall(t))x.add_row([m,n, result])print(x) def group_k(cipher,miyao):fg = list(cipher)MIC_k=[]MIC_I=[]MIC_J=[]pyl_k = []for i in range(miyao-1):group1 = fg[i::miyao]for n in range(i+1,miyao):group2 = fg[n::miyao]k = [0 for i in range(26)]for j in range(26):k[j] = count_group_MIC(group1, group2, j)pyl_k.append(k[j])if k[j]>0.060:m = jMIC_k.append(m)print("第%d組和第%d組之間偏移為%d時,交互重合指數為%.3f" % (i+1,n+1, m, k[m]))MIC_I.append(i+1)MIC_J.append(n+1)figure_k(pyl_k,miyao)return MIC_k,MIC_I,MIC_J def contact(k,i,j,miyao):k1, k2, k3, k4, k5, k6, k7, k8, k9 = sympy.symbols("k1 k2 k3 k4 k5 k6 k7 k8 k9")daishu=[k1,k2,k3,k4,k5,k6,k7,k8,k9]ds=daishu[0:miyao]MIC_ij = []sz=[]print("根據偏移量可得各個密鑰之間的關系:")for x,y,z in zip(i,j,k):t = 0print("%s-%s=%d"%(ds[x-1],ds[y-1],z))if ds[x-1]==k1:MIC_ij.append(ds[x - 1])if ds[x-1] not in MIC_ij and ds[y-1] in MIC_ij:t=1MIC_ij.append(ds[x-1])if ds[x-1] in MIC_ij and ds[y-1] not in MIC_ij:t = 1MIC_ij.append(ds[y- 1])if t==1:if ds[x-1]==k1:ds[x - 1]=0sz.append(ds[x - 1]-ds[y-1]-z)del ds[0]a = sympy.solve(sz,ds)gx=[]for m,n in a.items():gx.append(n)gx.insert(0,0)gx=[(26+i)%26 for i in gx]gxs=[i+k1 for i in gx]print("根據上式可得各個密鑰間的關系為",gxs)return gx def certain_miyao(k,cipher,miyaolen):for i in range(26):t=[(i+j)%26 for j in k]k1 = t * (len(cipher)// miyaolen + 1)k1=[chr((ord(i)-65-j)%26+65) for i,j in zip(cipher,k1)]d = {}for j in k1:if j in d:d[j] += 1else:d[j] = 1dict = sorted(d.items(), key=operator.itemgetter(1), reverse=True)k1="".join(k1)if dict[0][0]=='E':print("由單表古典密碼統計分析出現的字母頻率判斷可知:")t=[chr(i+65) for i in t]word = wordninja.split(k1)plain = ''for i in range(len(word)):plain += word[i]plain += ' 'print("當密鑰為%s時,明文為%s"%(t,plain)) if __name__ == "__main__":fp = open("密文3.txt", "r")cipher = ''for i in fp.readlines():cipher = cipher + ifp.close()cipher = alpha(cipher)figure(cipher)miyaolength=miyao_length(cipher)miyaolen=miyao_len(cipher)figure_len(miyaolen,cipher)k,i,j=group_k(cipher,miyaolen)contact_k=contact(k,i,j,miyaolen)certain_miyao(contact_k,cipher,miyaolen總結
以上是生活随笔為你收集整理的多表古典密码统计分析之Vigenere算法保姆级教学(含Kasiski测试法和重合指数法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java编程练习·编写USB接口模拟计算
- 下一篇: 打造你的专属埃菲尔塔