凯撒密码

本文最后更新于 2022年10月23日 上午

凯撒密码

经典的移位密码。
定义 \(ord()\)\(chr()\)\(ord('a') = 97\), \(chr(97) = 'a'\)。秘钥 \(K \in \{0, 25\}\)

1
2
3
4
5
6
7
8
9
10
11
def encryption(S, K):
res = ''
for c in S:
res += (ord(c) + K) % 26
return res

def decryption(S, K):
res = ''
for c in S:
res += (ord(c) - K) % 26
return res

破解方法

暴力

因为 \(|K| = 26\),所以枚举 26 次就能得到有意义的明文。

统计

因为凯撒密码不是概率加密,即同一个字符每一次加密的结果都是一样的,所以密文和明文的字母概率分布是相同的,所以对于有意义的文本,可以通过统计字母出现的频率,如下图,猜测出秘钥 K。 英文文本中字母的平均频率[1] 不难算出 \[ \sum_{i=0}^{25} p_i^2 \approx 0.065 \]\(q_i\) 表示第 \(i\) 个字符在密文中出现的频率(A 是第 \(0\) 个字符)。对于秘钥 \(k \in {0, .., 25}\)\[ I_k = \sum_{i=0}^{25} p_i * q_{(i+k) \mod 26} \approx 0.065 \] 核心代码如下。

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
p = {
0: 0.082,
1: 0.015,
2: 0.028,
3: 0.042,
4: 0.127,
5: 0.022,
6: 0.020,
7: 0.061,
8: 0.070,
9: 0.001,
10: 0.008,
11: 0.040,
12: 0.024,
13: 0.067,
14: 0.075,
15: 0.019,
16: 0.001,
17: 0.060,
18: 0.063,
19: 0.090,
20: 0.028,
21: 0.010,
22: 0.024,
23: 0.020,
24: 0.001,
25: 0.001
}


def attack(ciphertext):
n = len(ciphertext)
I = [0 for i in range(26)]
freq = [0 for i in range(26)]
for char in ciphertext:
freq[getIndex(char)] += 1
for i in range(26):
freq[i] /= n

eps = 0.005
res = -1
for key in range(0, 26):
for i in range(26):
I[key] += p[i] * freq[(i + key) % 26]
if abs(I[key] - 0.065) < eps:
res = key
eps = abs(I[key] - 0.065)
return res
完整代码

参考文献

  1. Introduction To Modern Cryptography ↩︎

凯撒密码
https://term-inator.github.io/2022/09/20/caesar-cipher/
作者
Sicong Chen
发布于
2022年9月20日
更新于
2022年10月23日
许可协议