1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| '''维吉尼亚破解''' import numpy as np import wordninja
def alpha(cipher): c = '' for i in range(len(cipher)): if (cipher[i].isalpha()): c += cipher[i] return c
def count_IC(cipher): count = [0 for i in range(26)] L = len(cipher) IC = 0.0 for i in range(len(cipher)): if (cipher[i].isupper()): count[ord(cipher[i]) - ord('A')] += 1 elif (cipher[i].islower()): count[ord(cipher[i]) - ord('a')] += 1 for i in range(26): IC += (count[i] * (count[i] - 1)) / (L * (L - 1)) return IC
def count_key_len(cipher, key_len): N = ['' for i in range(key_len)] IC = [0 for i in range(key_len)] for i in range(len(cipher)): m = i % key_len N[m] += cipher[i] for i in range(key_len): IC[i] = count_IC(N[i]) print("长度为%d时,平均重合指数为%.5f" % (key_len, np.mean(IC))) return np.mean(IC)
def length(cipher): key_len = 0 mins = 100 aver = 0.0 for i in range(1, 10): k = count_key_len(cipher, i) if (abs(k - 0.065) < mins): mins = abs(k - 0.065) key_len = i aver = k print("密钥长度为%d,此时重合指数每组的平均值为%.5f" % (key_len, aver)) return key_len
def count_MIC(c1, c2, n): count_1 = [0 for i in range(26)] count_2 = [0 for i in range(26)] L_1 = len(c1) L_2 = len(c2) MIC = 0 for i in range(L_1): if (c1[i].isupper()): count_1[ord(c1[i]) - ord('A')] += 1 elif (c1[i].islower()): count_1[ord(c1[i]) - ord('a')] += 1 for i in range(L_2): if (c2[i].isupper()): count_2[(ord(c2[i]) - ord('A') + n + 26) % 26] += 1 elif (c2[i].islower()): count_2[(ord(c2[i]) - ord('a') + n + 26) % 26] += 1 for i in range(26): MIC += count_1[i] * count_2[i] / (L_1 * L_2) return MIC
def count_n(c1, c2): n = 0 mins = 100 k = [0.0 for i in range(26)] for i in range(26): k[i] = count_MIC(c1, c2, i) if (abs(k[i] - 0.065) < mins): mins = abs(k[i] - 0.065) n = i return n
def group_k(cipher, key_len): N = ['' for i in range(key_len)] MIC = [0 for i in range(key_len)] s = [0 for i in range(key_len)] for i in range(len(cipher)): m = i % key_len N[m] += cipher[i] for i in range(1, key_len): s[i] = count_n(N[0], N[i]) MIC[i] = count_MIC(N[0], N[i], s[i]) print("第1组和第%d组之间偏移为%d时,互重合指数为%.5f" % (i + 1, s[i], MIC[i])) return s
def miyao(key_len, s, k): mi = ['' for i in range(key_len)] for i in range(key_len): s[i] = -s[i] + k mi[i] = chr((s[i] + 26) % 26 + ord('a')) print("第一个偏移量为%d,密钥为%s时" % (k, mi)) return s
def the_end(cipher, key_len, s): plain = '' i = 0 while (i < len(cipher)): for j in range(key_len): if (cipher[i].isupper()): plain += chr((ord(cipher[i]) - ord('A') - s[j] + 26) % 26 + ord('A')) else: plain += chr((ord(cipher[i]) - ord('a') - s[j] + 26) % 26 + ord('a')) i += 1 if (i == len(cipher)): break return plain
if __name__ == "__main__": cipher = 'Ofqi ht wj, fdpsxvp, ityg cgux tqi egtbvvb. Lx ypfu iaov flt woa nc bngv ugt, uiv lqjtznp ut iweksgx hjrr stm cj dpk wp kft yivlpt. Pvge ut tfg zl qncarli asccrw, wsckf xl onc zjm ipzkpzwprzax. Kg jcawco kfxgy qw gi. Mvg uynl gvicivv qlr xg op vlsesuj txlhc. Jm lx uq rzdnh qlp exhvp rplyu, yygwza rupks qw mjk zkjraxgu rribhwuc ihkcib abtg.Rls mvg jcrhbf ggtvs kj "ztewg5!_"' cipher = alpha(cipher) key_len = length(cipher) s = group_k(cipher, key_len) m = s.copy() for k in range(26): s = m.copy() s = miyao(key_len, s, k) plain = the_end(cipher, key_len, s) print(plain[0:20]) print("参考输出,请输入第一个子串的偏移量:", end='') k = int(input()) m = miyao(key_len, m, k) plain = the_end(cipher, key_len, m)
'''对英文文本进行分词''' word = wordninja.split(plain) plain = '' for i in range(len(word)): plain += word[i] plain += ' ' print("明文为\n" + plain)
|