首页/我的作品/密码学/3.5 动手实验:用Python破解凯撒密码
密码学:守护数字世界的秘密

3.5 动手实验:用Python破解凯撒密码

第 20 / 78 篇 · Crazy Boy

在前几节,我们学习了凯撒密码的原理——它只是把字母表“转”起来,每个字母向后(或向前)移动固定的位数。加密和解密都需要知道那个秘密的移位数(密钥)。

但你有没有想过:如果我们不知道密钥,该怎么破解它?

凯撒密码的密钥只有25种可能(移0位没意义,移26位等于没移)。在计算机出现之前,人工逐个尝试25种移位可能很麻烦,但今天,我们只需要几行Python代码,就能在一秒钟内暴力破解任何凯撒密文。

实验目标

编写一个Python程序,输入一段凯撒密文,自动尝试所有25种可能的移位,输出看起来最像英文的明文。

第一步:加密和解密函数

首先,我们需要一个函数来对字母进行移位操作。为了简单起见,我们只处理大写字母,忽略非字母字符(保留原样)。

def caesar_shift(text, shift):
"""将文本中的每个字母向后移动shift位(支持负数表示向前)"""
result = []
for char in text:
if char.isalpha():
# 只处理大写字母,小写统一转为大写(你也可以保留大小写)
base = ord('A')
shifted = (ord(char.upper()) - base + shift) % 26 + base
result.append(chr(shifted))
else:
result.append(char)
return ''.join(result)

def caesar_encrypt(plaintext, shift):
return caesar_shift(plaintext, shift)

def caesar_decrypt(ciphertext, shift):
# 解密就是反向移位
return caesar_shift(ciphertext, -shift)

第二步:如何判断哪个结果像英文?

暴力枚举会得到25个可能的结果,我们需要从中选出真正的英文句子。最简单的办法是:检查结果中是否包含常见的英文单词。比如,如果某个结果包含了单词 “THE”、”AND”、”OF” 等,它很可能就是正确的。

我们准备一个常用英文单词列表(这里只列出几个最常见的单词作为示例,你可以自己扩展):

COMMON_WORDS = {"THE", "AND", "OF", "TO", "IN", "IS", "IT", "YOU", "THAT"}

然后写一个函数,计算每个结果中包含这些常见单词的数量(忽略大小写)。得分最高的那个就是最可能的明文。

def score_text(text):
"""根据常见单词出现次数打分"""
words = text.upper().split()
score = 0
for word in words:
if word in COMMON_WORDS:
score += 1
return score

第三步:暴力破解函数

现在,我们把所有移位都试一遍,对每个结果打分,返回得分最高的那个。

def crack_caesar(ciphertext):
best_plaintext = None
best_score = -1
best_shift = 0
for shift in range(1, 26): # 尝试所有可能的移位
plain = caesar_decrypt(ciphertext, shift)
current_score = score_text(plain)
if current_score > best_score:
best_score = current_score
best_plaintext = plain
best_shift = shift
return best_shift, best_plaintext

第四步:测试一下

假设我们截获了一段密文:"WKLV LV D VHFUHW PHVVDJH"(这是英文 “THIS IS A SECRET MESSAGE” 用凯撒密码移3位得到的)。让我们用程序破解:

cipher = "WKLV LV D VHFUHW PHVVDJH"
shift, plain = crack_caesar(cipher)
print(f"发现密钥: {shift}")
print(f"明文: {plain}")

运行结果:

发现密钥: 3
明文: THIS IS A SECRET MESSAGE

成功了!

进一步改进

上面的代码虽然能工作,但有一些可以优化的地方:

  1. 大小写和标点:当前代码把所有字母转成了大写,忽略了原始的大小写。你可以修改函数保留大小写,或者用更智能的方法。
  2. 词库扩充:COMMON_WORDS 列表越大,判断越准确。你可以从网上下载英文常用词列表(比如1000个常见词)来提高准确率。
  3. n-gram统计:更高级的方法是使用字母组合的统计模型(如字母对、三字母组的频率),而不是单词列表。这需要一些语言学数据,但破解效果更好。
  4. 处理短文本:如果密文很短,可能不包含任何常见单词,此时需要其他启发式(比如计算字母频率与英文标准频率的吻合度)。

动手挑战

  1. 用上面的程序破解下面这段密文(提示:密钥是某个数字):
    "QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD"

  2. 修改代码,让它支持小写字母和空格,并保留原始的大小写格式。

  3. 尝试用字母频率评分(例如计算每个字母的频率与英文标准频率的差异)来替代单词列表,看看哪种方法在短文本中表现更好。

小结

通过这个动手实验,你亲手实现了一个能自动破解凯撒密码的工具。这让你亲身体验到:在计算机面前,简单的移位密码毫无安全性可言。但更重要的是,你学会了如何用编程思维解决实际问题——把破译过程分解为“枚举所有可能”和“评分选择最优”两个步骤。这种思路在密码分析中无处不在。

下一节,我们将进入更复杂的单表替换密码的破解,你会发现,虽然方法不同,但“统计”和“猜测”依然是核心。