美文网首页
维吉尼亚密码(Vigenere)(二)

维吉尼亚密码(Vigenere)(二)

作者: 金卫岩 | 来源:发表于2022-03-09 09:01 被阅读0次

上一篇文章介绍了维吉尼亚密码的加解密过程,下面针对解密问题附上完整代码。(由于在程序运行过程中我是分步进行以便查看结果,因此代码段会涉及多次调用密文文档文件,当然,也可以将几个代码块融合在一起形成一个完整的代码文件)

计算密钥长度

#-*- coding:utf-8 –*-
def c_alpha(cipher):   # 去掉非字母后的密文
    cipher_alpha = ''
    for i in range(len(cipher)):
        if (cipher[i].isalpha()):
            cipher_alpha += cipher[i]
    return cipher_alpha

# 计算cipher的重合指数
def count_CI(cipher):
    N = [0.0 for i in range(26)]
    cipher = c_alpha(cipher)
    L = len(cipher)
    if cipher == '':
        return 0
    else:
        for i in range(L):     #计算所有字母的频数,存在数组N当中
            if (cipher[i].islower()):
                 N[ord(cipher[i]) - ord('a')] += 1
            else:
                 N[ord(cipher[i]) - ord('A')] += 1
    CI_1 = 0
    for i in range(26):
        CI_1 += ((N[i] / L) * ((N[i]-1) / (L-1)))
    return CI_1

# 计算秘钥长度为 key_len 的重合指数
def count_key_len_CI(cipher,key_len):        
    un_cip = ['' for i in range(key_len)]    # un_cip 是分组 
    aver_CI = 0.0
    count = 0
    for i in range(len(cipher_alpha)):
        z = i % key_len
        un_cip[z] += cipher_alpha[i]
    for i in range(key_len):
        un_cip[i]= count_CI(un_cip[i])
        aver_CI += un_cip[i]
    aver_CI = aver_CI/len(un_cip)
    return aver_CI

## 找出最可能的前十个秘钥长度
def pre_10(cipher):
    M = [(1,count_CI(cipher))]+[(0,0.0) for i in range(49)]
    for i in range(2,50):
        M[i] = (i,abs(0.065 - count_key_len_CI(cipher,i)))
    M = sorted(M,key = lambda x:x[1])   #按照数组第二个元素排序
    for i in range(1,10):
        print (M[i])

F = [
0.0651738, 0.0124248, 0.0217339,
0.0349835, 0.1041442, 0.0197881,
0.0158610, 0.0492888, 0.0558094,
0.0009033, 0.0050529, 0.0331490,
0.0202124, 0.0564513, 0.0596302,
0.0137645, 0.0008606, 0.0497563,
0.0515760, 0.0729357, 0.0225134,
0.0082903, 0.0171272, 0.0013692,
0.0145984, 0.0007836
]       # 英文字符频率。
fp = open("F:\CTF\CTF资料\i春秋\代码\Crypto\Vigenere\Vigenere.txt","r")
cipher = '' 
for i in fp.readlines():
    cipher = cipher + i    
fp.close()
cipher_alpha = c_alpha(cipher)
print ("秘钥长度为:")
pre_10(cipher)

计算密钥

#-*- coding:utf-8 –*-
def c_alpha(cipher):   # 去掉非字母后的密文
    cipher_alpha = ''
    for i in range(len(cipher)):
        if (cipher[i].isalpha()):
            cipher_alpha += cipher[i]
    return cipher_alpha

# 计算cipher的重合指数
def count_CI(cipher):
    N = [0.0 for i in range(26)]
    cipher = c_alpha(cipher)
    L = len(cipher)
    if cipher == '':
        return 0
    else:
        for i in range(L):     #计算所有字母的频数,存在数组N当中
            if (cipher[i].islower()):
                 N[ord(cipher[i]) - ord('a')] += 1
            else:
                 N[ord(cipher[i]) - ord('A')] += 1
    CI_1 = 0
    for i in range(26):
        CI_1 += ((N[i] / L) * ((N[i]-1) / (L-1)))
    return CI_1

# 计算秘钥长度为 key_len 的重合指数
def count_key_len_CI(cipher,key_len):        
    un_cip = ['' for i in range(key_len)]    # un_cip 是分组 
    aver_CI = 0.0
    count = 0
    for i in range(len(cipher_alpha)):
        z = i % key_len
        un_cip[z] += cipher_alpha[i]
    for i in range(key_len):
        un_cip[i]= count_CI(un_cip[i])
        aver_CI += un_cip[i]
    aver_CI = aver_CI/len(un_cip)
    return aver_CI

## 找出最可能的前十个秘钥长度
def pre_10(cipher):
    M = [(1,count_CI(cipher))]+[(0,0.0) for i in range(49)]
    for i in range(2,50):
        M[i] = (i,abs(0.065 - count_key_len_CI(cipher,i)))
    M = sorted(M,key = lambda x:x[1])   #按照数组第二个元素排序
    for i in range(1,10):
        print (M[i])

F = [
0.0651738, 0.0124248, 0.0217339,
0.0349835, 0.1041442, 0.0197881,
0.0158610, 0.0492888, 0.0558094,
0.0009033, 0.0050529, 0.0331490,
0.0202124, 0.0564513, 0.0596302,
0.0137645, 0.0008606, 0.0497563,
0.0515760, 0.0729357, 0.0225134,
0.0082903, 0.0171272, 0.0013692,
0.0145984, 0.0007836
]       # 英文字符频率。
# 猜测单个秘钥得到的重合指数
def count_CI2(cipher,n):     # n 代表我们猜测的秘钥,也即偏移量
    N = [0.0 for i in range(26)]
    cipher = c_alpha(cipher)
    L = len(cipher)
    for i in range(L):     #计算所有字母的频数,存在数组N当中
        if (cipher[i].islower()):
            N[(ord(cipher[i]) - ord('a') - n)%26] += 1
        else:
            N[(ord(cipher[i]) - ord('A') - n)%26] += 1  
    CI_2 = 0
    for i in range(26):
        CI_2 += ((N[i] / L) * F[i])
    return CI_2

def one_key(cipher,key_len):
    un_cip = ['' for i in range(key_len)]   
    cipher_alpha = c_alpha(cipher)
    for i in range(len(cipher_alpha)):     # 完成分组工作
        z = i % key_len
        un_cip[z] += cipher_alpha[i]
    for i in range(key_len):
        print (i)
        pre_5_key(un_cip[i])     ####这里应该将5个分组的秘钥猜测全部打印出来

## 找出前5个最可能的单个秘钥
def pre_5_key(cipher):
    M = [(0,0.0) for i in range(26)]
    for i in range(26):
        M[i] = (chr(ord('a')+i),abs(0.065 - count_CI2(cipher,i)))
    M = sorted(M,key = lambda x:x[1])   #按照数组第二个元素排序

    for i in range(10):
        print (M[i])

key_len = 8   #输入猜测的秘钥长度
fp = open("F:\CTF\CTF资料\i春秋\代码\Crypto\Vigenere\Vigenere.txt","r")
cipher = '' 
for i in fp.readlines():
    cipher = cipher + i    
fp.close()
one_key(cipher,key_len)

破译密文

def decrypto (miwen,key):
    mingwen = [0]*(len(miwen))
    count = 0
    for i in range (len(miwen)):
        if(miwen[i].isalpha()):
            if(miwen[i].isupper()):
                offset1 = ord(key[(i-count)%len(key)])-ord('a')
                mingwen[i] = chr(((ord(miwen[i])+ord('A'))-offset1)%26+ord('A'))
            else:
                offset2 = ord(key[(i-count)%len(key)])-ord('a')
                mingwen[i] = chr(((ord(miwen[i])-ord('a'))-offset2)%26+ord('a'))                
        else:
            mingwen[i]=miwen[i]
            count = count + 1
    return mingwen

fp = open("F:\CTF\CTF资料\i春秋\代码\Crypto\Vigenere\Vigenere.txt","r")
cipher = '' 
for i in fp.readlines():
    cipher = cipher + i    
fp.close()
mingwen = decrypto(cipher,'asterism')
mingwen = [str(i) for i in mingwen]
mingwen = ''.join(mingwen)
print(mingwen)

相关文章

  • 维吉尼亚密码(Vigenere)(二)

    上一篇文章介绍了维吉尼亚密码的加解密过程,下面针对解密问题附上完整代码。(由于在程序运行过程中我是分步进行以便查看...

  • 维吉尼亚密码(Vigenere)(一)

    维吉尼亚密码的原理与凯撒密码类似,其实是凯撒的一种强化和变形,通过使加密相同明文的秘钥不同,来掩盖字符的频率。 我...

  • Vigenere 密码破译

    Vigenere 密码破译 from my csdn blog 信息安全原理 hw1-2 Vignere: ktb...

  • 1.3 外国历史

    象形文字、棋盘密码、兽栏法、摩斯电码等,做替换,是一种编码 凯撒密码移位密码/加法密码 Vigenere密码分组加...

  • python实现维吉尼亚秘钥破解

    关于维吉尼亚密码,百度百科中有着较为详细的描述:维吉尼亚密码——百度百科维吉尼亚密码的原理与凯撒密码类似,其实是凯...

  • 维吉尼亚密码

    维吉尼亚密码是以法国外交官、密码学家布莱斯·德·维吉尼亚的名字命名的,不过不是他本人发明的。 【加密原理】...

  • 维吉尼亚密码加密文件

    一.维吉尼亚密码加密文本文件 要求:用维吉尼亚密码实 现加密任意文本文件,注意用控制台方式实现。输入格式:>-e/...

  • 基于频率分析的Vigenere破解

    Vigenere密码简介: 信息代码:X=(x1,x2,…,xd)∈(Z/26)d 密钥:K=(k1,k2,…,k...

  • 维吉尼亚密码加密解密对照表

    采用替代密码算法中的维吉尼亚密码方法,密文C=“HEADVIGENERE”,密钥K=KEY,求明文P 将密文HEA...

  • 密码那些事儿(十)

    在说维吉尼亚加密法的破解方法之前,有必要来回顾一下它的加密原理。 维吉尼亚加密法是由26套密码组成的表,我们默认要...

网友评论

      本文标题:维吉尼亚密码(Vigenere)(二)

      本文链接:https://www.haomeiwen.com/subject/erftdrtx.html