关于无密钥维吉尼亚密码的破解

具体数学原理。。。我也没不太知道怎么解释。。。直接贴别人的理解也不太好,但是脚本写出来啦,就直接贴脚本咯~

import re, math

def openfile(fileName):
    file = open(fileName,'r')
    text = file.read()
    file.close();
    text = text.replace('\n','')
    return text

def charOffset(char, offset):
    if(offset < 0):
        offset += 26
    if char.islower():
        return chr((ord(char) - 97 + offset) % 26 + 97)
    else:
        return chr((ord(char) - 65 + offset) % 26 + 65)

def Vigenere(strIn, key, encode):
    strOut = ""
    j = 0
    for c in strIn:
        if c.isalpha():
            offset = ord(key[j % len(key)]) - 97
            j += 1
            if encode == False:
                offset = -offset
            strOut += charOffset(c, offset)
        else:
            strOut += c
    return strOut

def deVigenereAuto(ciphertext):
    best_key = ""
    count = []
    cipherMin = ciphertext.lower()
    cipherMin = re.sub('[^a-z]', '', ciphertext.lower())
    freq = [8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966, 0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074];
    for best_len in range(3, 13):
        sum = 0
        for j in range(0, best_len):
            for i in range(0, 26):
                count.append(0)
            i = j
            while i < len(cipherMin):
                count[ord(cipherMin[i]) - 97] += 1
                i += best_len
            ic = 0
            num = len(cipherMin)/best_len
            for i in range(0, len(count)):
                ic += math.pow(count[i]/num, 2)
            sum += ic
        if sum/best_len > 0.065:
            break
    for j in range(0, best_len):
        for i in range(0, 26):
            count[i] = 0
        i = j
        while i < len(cipherMin):
            count[ord(cipherMin[i]) - 97] += 1
            i += best_len
        max_dp = -1000000
        best_i = 0
        for i in range(0, 26):
            cur_dp = 0.0
            for k in range(0, 26):
                cur_dp += freq[k] * count[(k + i) % 26]
            if cur_dp > max_dp:
                max_dp = cur_dp
                best_i = i
        best_key += chr(best_i + 97)
    print "best_key : " + best_key
    print "plaintext : " + Vigenere(ciphertext, best_key, False)

if __name__ == '__main__':
    ciphertext = openfile('ciphertext2.txt')
    a = raw_input("did you have key?(Y/N)")
    a = a.upper()
    if a == 'N':
        deVigenereAuto(ciphertext)
    if a == 'Y':
        key = raw_input("key?")
        print "plaintext : " + Vigenere(ciphertext, key, False)

发布者

Aslin

学习ing~

发表评论

电子邮件地址不会被公开。 必填项已用*标注