【密码学】基于英文字母自然统计规律破解凯撒算法加密

1. 前言

凯撒密码是一种古老的加密算法,至今也被应用在某些加密算法的过程中。一般而言,破解凯撒密码需要密钥,但是由于加密空间太小,解密可以穷举进行。因此本文给出了一种基于统计的解密算法,这种算法思想也可以应用到其他场合。

2. 算法

2.1 凯撒加密算法

凯撒加密算法是采取字母移位的思路进行,加密公式如下:

word = (word + x) mod 26

 根据鸽巢原理可知,穷举26次必然能得到加密原文。

2.2 基于统计分析解密算法

算法求解前提假设:加密原文符合英文字母自然统计规律。

首先列出英语字母自然频率分布表:

【密码学】基于英文字母自然统计规律破解凯撒算法加密_第1张图片

将频率分布表按照出现频率从高到低进行排序,得到:

statistics_list = [w1,w2, ... ,w25,w26 ]

随后,对于密文序列 words,也按照字母出现频率从高到低进行排序,得到:

candidate_list = [w1',w2', ... ,w25',w26']

 采用欧几里得距离定义差异值 diffvalue,公式如下:

diffvalue = (x1-x1')^2 + (x2-x2')^2 + ... + (x26-x26')^2 //xi、xi'代表同一字母在不同列表中的位置

综上,算法思路:暴力枚举26种情况,并求得每种情况下的 diffvalue,最后选择 diffvalue 最小的答案作为加密原文输出。如果加密原文不符合英文字母统计规律(如一堆无意义的字母组合),则算法无法输出正确结果。在加密原文长度过小的情况下,同样不符合英文字母自然统计规律,也可能得到错误结果。综上,算法最终输出三种 diffvalue 最小的答案作为最可能的结果。

3. 代码实现

# statistical character list
sta_chs = ['e', 't', 'a', 'o', 'i', 'n', 's', 'h', 'r', 'd', 'l', 'c',
           'u', 'm', 'w', 'f', 'g', 'y', 'p', 'b', 'v', 'k', 'j', 'x', 'q', 'z']

# before encrypt
original_text = ""
# encypted
encrypted_text = ""
# decrypt in force-enumeration way (without key)
force_list = []


# encrypt with caesar encryption method
def caesar_encrypt(key_num):
    global encrypted_text
    encrypted_text = ''
    for ch in original_text:
        if ch.isalpha():
            num = ord(ch)
            num += key_num
            if ch.isupper():
                if num > ord('Z'):
                    num -= 26
                elif num < ord('A'):
                    num += 26
            else:
                if num > ord('z'):
                    num -= 26
                elif num < ord('a'):
                    num += 26
            encrypted_text += chr(num)
        else:
            encrypted_text += ch
    print(encrypted_text)


def getkey(x):
    return x[1]


# decrypt without key (force enumeration)
def statistics_decrypt():
    global force_list
    force_list.clear()
    key = 1
    while key <= 26:
        temp = caesar_decrypt(key)
        templist = []
        templist.append(temp)
        tlist = []
        for i in range(26):
            tlist1 = []
            tlist1.append(i)
            tlist1.append(0)
            tlist.append(tlist1)
        temp = temp.lower()
        for tch in temp:
            if tch.isalpha():
                tlist[ord(tch)-ord('a')][1] += 1
        tlist.sort(key=getkey, reverse=True)
        cost = 0
        idx = 0
        while idx<26:
            item=tlist[idx][0]
            num=ord('a')+item
            idy=0
            while idy<26:
                if num == ord(sta_chs[idy]):
                    cost+=(idy-idx)**2
                    break
                idy+=1
            idx+=1
        templist.append(cost)
        force_list.append(templist)
        key += 1
    force_list.sort(key=getkey)
    print(force_list)
    print(len(force_list))


def get_statistics_answer():
    return force_list[0:3:1]


if __name__ == "__main__":
    # global original_text
    original_text = "ab AB hoW are you?I'm fine thank you.and you?"
    caesar_encrypt(2)
    statistics_decrypt()
    print(get_statistics_answer())

4. 实验结果

最终加上了界面实现,效果如下:

【密码学】基于英文字母自然统计规律破解凯撒算法加密_第2张图片

解密后:

【密码学】基于英文字母自然统计规律破解凯撒算法加密_第3张图片

你可能感兴趣的:(专业课,算法)