Caesar
1. 概念
凯撒密码得名于古罗马的尤利乌斯·凯撒(Julius Caesar),据称他当年使用这种方式与将军们进行秘密通信。
它的核心原理非常简单:位移(Shift)。
将明文中的每一个字母,按照字母表顺序向后(或向前)移动固定的位数,替换成新的字母。
2. 加密原理与过程
假设我们要发送信息,我们首先需要约定一个密钥(Key),也就是偏移量。
-
明文 (Plaintext): 原始信息。
-
密钥 (Key): 移动的位数(例如:3)。
-
密文 (Ciphertext): 加密后的信息。
示例演示
假设 密钥 = 3(这是凯撒当年最常用的偏移量):
-
A 向后移动 3 位 \(\rightarrow\) D
-
B 向后移动 3 位 \(\rightarrow\) E
-
C 向后移动 3 位 \(\rightarrow\) F
-
...
-
X 向后移动 3 位 \(\rightarrow\) A (注意:这里发生了“回绕”,到了字母表末尾这就回到开头)
实际例子:
-
明文:
HELLO WORLD -
加密:
-
H (+3) \(\rightarrow\) K
-
E (+3) \(\rightarrow\) H
-
L (+3) \(\rightarrow\) O
-
L (+3) \(\rightarrow\) O
-
O (+3) \(\rightarrow\) R
-
...
-
-
密文:
KHOOR ZRUOG
3. 数学表达(模运算)
在计算机科学和CTF竞赛中,我们通常用数学公式来描述它。
首先将字母映射为数字:\(A=0, B=1, C=2, ..., Z=25\)。
-
加密公式:
\[ E_n(x) = (x + n) \mod 26 \](其中 \(x\) 是明文数字,\(n\) 是密钥,\(E_n(x)\) 是密文)
-
解密公式:
\[ D_n(x) = (x - n) \mod 26 \](如果减法结果为负数,需要加 26 使其变为正数)
关键点:模运算 (Mod)
之所以要 \(\mod 26\),是为了处理“Z”之后的越界问题,让字母表形成一个闭环。
4. 常见的变体:ROT13
在程序员社区和网络论坛中,最著名的凯撒密码变体是 ROT13。
它的密钥固定为 13。
-
特点: 因为 26 的一半是 13,所以加密和解密是同一个操作。
-
加密:\(x + 13\)
-
再加密(即解密):\((x + 13) + 13 = x + 26 = x\)
-
-
用途: 常用于隐藏剧透内容或简单的谜题,因为它不需要解密密钥,再执行一次ROT13就能看到原文。
5. 如何破解凯撒密码?
由于凯撒密码极其简单,它没有任何安全性可言。主要有两种破解方法:
A. 暴力破解
英语字母表只有 26 个字母。如果不算移动 0 位(即原文),可能的密钥只有 25 个。
攻击者只需要把这 25 种情况全部列出来,肉眼观察哪一行是有意义的单词即可。
B. 频率分析法
如果密文非常长,我们可以统计密文中每个字母出现的频率。
-
在标准英语中,字母 E 的出现频率是最高的(约 12.7%),其次是 T, A, O, I, N。
-
破解逻辑: 如果你统计密文,发现字母 H 出现的次数最多,那么很有可能 H 就是明文中的 E。
-
计算偏移量:\(H (7) - E (4) = 3\)。那么密钥很可能就是 3。
6. Python 代码实现
这是CTF中常用的脚本结构,包含了加密和解密功能:
def caesar_cipher(text, shift, mode='encrypt'):
result = ""
# 如果是解密,将偏移量变为负数
if mode == 'decrypt':
shift = -shift
for char in text:
# 处理大写字母
if char.isupper():
# ord('A') = 65. 将字符转为0-25范围,位移,取模,再转回ASCII
new_char = chr((ord(char) - 65 + shift) % 26 + 65)
result += new_char
# 处理小写字母
elif char.islower():
new_char = chr((ord(char) - 97 + shift) % 26 + 97)
result += new_char
# 非字母字符(如空格、标点)保持不变
else:
result += char
return result
# 测试
plaintext = "Hello, World!"
key = 3
# 加密
ciphertext = caesar_cipher(plaintext, key, mode='encrypt')
print(f"加密后: {ciphertext}") # 输出: Khoor, Zruog!
# 解密
decrypted = caesar_cipher(ciphertext, key, mode='decrypt')
print(f"解密后: {decrypted}") # 输出: Hello, World!