Sky's blog

密码学课程设计一之维吉尼亚唯密文破解

Word count: 711 / Reading time: 4 min
2017/12/24 Share

前记

今天终终终终终终终终终终于考完试了,结束了1周考3门,3周考5门的窘况,于是开始补Blog,写一下这3周来弄的东西

维吉尼亚唯密文爆破

这里利用了重合指数法和互重合指数法:
重合指数法:
猜测密钥长度
互重合指数法:
猜测相对位移长度

重合指数法

1
2
3
4
5
6
7
8
9
10
def chzs(input): #重合指数法
num_list = [0]*26
for i in range(0,len(input)):
ord_input = ord(input[i])-97
num_list[ord_input] +=1
n = len(input)
res = 0
for i in range(0,26):
res += num_list[i]*(num_list[i]-1)
return float(res)/((n-1)*n)

计算密钥长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def len_key(input):
may_d = 0
index_d = 0
for d in range(1,10):
str_list = [""] * 10
for i in range(0,len(input)):
str_list[i%d] += input[i]
ch_sum = 0
ch_time = 0
for k in range(0, len(str_list)):
if str_list[k] !="":
ch_sum += chzs(str_list[k])
ch_time +=1
k1 = abs(ch_sum / ch_time - 0.065)
k2 = abs(may_d - 0.065)
if k1<k2:
may_d = ch_sum / ch_time
index_d = d
if abs(may_d-0.065)<0.006:
return index_d
else:
print "与0.065最接近的数为:",may_d,"\n","此时长度为:",index_d

计算相对位移

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
def xd_d(input): #相对位移
key_len = len_key(input)
d_list = []
str_list = [""]*key_len
for i in range(0,len(input)):
str_list[i%key_len] += input[i]
sll = len(str_list)
for i in range(0,len(str_list)):
num_list_i = [0] * 26
for k in str_list[i]:
i_c = ord(k) - 97
num_list_i[i_c] += 1
for j in range(i+1,sll):
num_list_j = [0] * 26
for k in str_list[j]:
j_c = ord(k) - 97
num_list_j[j_c] += 1
may_res = 0
may_d = 0
n_j = len(str_list[j])
n_i = len(str_list[i])
res = 0
for d in range(1,26):
for ni in range(0,26):
res += num_list_i[ni]*num_list_j[(ni+d)%26]
res = float(res)/(n_i*n_j)
if abs(res-0.065)<= abs(may_res-0.065):
may_res = res
may_d = d
if abs(may_res-0.065)<=0.015:
if j-i == 1:
d_list.append(may_d)
return d_list

根据相对距离生成密钥

1
2
3
4
5
6
7
8
9
def key_gen(input):
d_list = xd_d(input)
key_list = []
for j in range(0,26):
key = chr(j+97)
for i in range(0,len(d_list)):
key += chr(((ord(key[i])-97)+d_list[i])%26+97)
key_list.append(key)
return key_list

一般维吉尼亚解密程序

1
2
3
4
5
6
7
8
9
10
11
def vgdec(input , key):
mes = ""
for i in range(0,len(input)):
j = i % len(key)
v_input = ord(input[i])-97
v_key = ord(key[j])-97
v_mes = v_input-v_key
if v_mes < 0 :
v_mes = 26+v_mes
mes += chr(v_mes+97)
return mes

暴力破解主函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def force_dec(input):
res = key_gen(input)
e_time = 0
key_res = ""
mes_res = ""
for i in res:
mes = vgdec(input,i)
mes_num_list = [0]*26
for k in mes:
v_k = ord(k)-97
mes_num_list[v_k] +=1
if mes_num_list[ord("e")-97]>e_time:
e_time = mes_num_list[ord("e")-97]
key_res = i
mes_res = mes
print "根据统计分析,密钥可能为:",key_res
print "此密钥解密后,你的文本为:",mes_res

后记

至于原理……如果我后期复习密码学准备考试的时候可能会写吧23333333

CATALOG
  1. 1. 前记
  2. 2. 维吉尼亚唯密文爆破
    1. 2.1. 重合指数法
    2. 2.2. 计算密钥长度
    3. 2.3. 计算相对位移
    4. 2.4. 根据相对距离生成密钥
    5. 2.5. 一般维吉尼亚解密程序
    6. 2.6. 暴力破解主函数
  3. 3. 后记