1. 项目概述:用Python实现古典密码破译
在信息安全领域,替换密码是最基础的加密方式之一,也是理解现代加密算法的入门钥匙。这种将明文字母按固定规则替换为密文字母的加密方法,最早可以追溯到古罗马时期的凯撒密码。虽然现代加密技术已经发展出AES、RSA等复杂算法,但学习替换密码的破译原理仍然是安全工程师的必修课。
我最近在整理密码学教学材料时,重新编写了一套Python实现的替换密码破译工具。相比网上常见的示例代码,这个版本特别注重三个实用特性:一是支持自定义字符集(可处理包含数字、符号的文本),二是内置了基于词频统计的智能分析模块,三是提供了交互式的破译过程可视化。下面我就从原理到实现,完整分享这个项目的技术细节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 密码学基础与破译原理
2.1 替换密码的工作机制
替换密码的核心在于建立两个字符集之间的映射关系。以经典的凯撒密码为例:
code复制明文字符集:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字符集:DEFGHIJKLMNOPQRSTUVWXYZABC
当选择位移量为3时,"HELLO"加密后变为"KHOOR"。更通用的单表替换密码则允许任意排列组合,比如:
code复制明文字符集:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字符集:QAZWSXEDCRFVTGBYHNUJMIKOLP
这种加密方式的关键弱点在于:它保留了原始文本的统计特征。英语中字母'e'的出现频率约为12.7%,而'z'只有0.07%——这种差异会完整反映在密文中。
2.2 频率分析破译法
基于统计的频率分析是破译替换密码的核心武器。其操作流程如下:
- 统计密文中各字符出现频率
- 与目标语言的字母频率表对比
- 将高频密文字符对应为高频明文字符
- 通过部分匹配结果推断其他字符映射
英语的标准字母频率分布为:
code复制e(12.7%), t(9.1%), a(8.2%), o(7.5%), i(7.0%), n(6.7%), s(6.3%), h(6.1%), r(6.0%), d(4.3%), l(4.0%), c(2.8%), u(2.8%), m(2.4%), w(2.4%), f(2.2%), g(2.0%), y(2.0%), p(1.9%), b(1.5%), v(1.0%), k(0.8%), j(0.2%), x(0.2%), q(0.1%), z(0.1%)
注意:实际分析时需要准备至少100个字符的密文,短文本的统计结果可能严重偏离理论值
3. Python实现详解
3.1 核心类设计
我们创建CipherBreaker类来封装所有功能:
python复制class CipherBreaker:
def __init__(self, ciphertext, lang='en'):
self.ciphertext = ciphertext.lower()
self.lang = lang
self.freq = {}
self.mapping = {}
self.load_language_profile(lang)
def load_language_profile(self, lang):
"""加载指定语言的字母频率表"""
self.lang_profile = {
'en': {'e':12.7, 't':9.1, 'a':8.2, 'o':7.5, 'i':7.0,
'n':6.7, 's':6.3, 'h':6.1, 'r':6.0, 'd':4.3}
# 可扩展其他语言
}.get(lang, {})
3.2 频率统计模块
实现字符频率分析的核心方法:
python复制def analyze_frequency(self):
"""统计密文字符频率"""
total = len([c for c in self.ciphertext if c.isalpha()])
counter = collections.Counter(
c for c in self.ciphertext if c.isalpha()
)
self.freq = {char: count/total*100
for char, count in counter.most_common()}
3.3 智能映射算法
基于频率匹配的自动推导逻辑:
python复制def build_mapping(self):
"""建立字符映射关系"""
cipher_chars = [k for k in self.freq.keys()]
lang_chars = [k for k in sorted(
self.lang_profile.keys(),
key=lambda x: -self.lang_profile[x]
)]
# 高频字符优先匹配
min_len = min(len(cipher_chars), len(lang_chars))
for i in range(min_len):
self.mapping[cipher_chars[i]] = lang_chars[i]
3.4 交互式修正功能
考虑到自动分析可能存在误差,我们增加人工干预接口:
python复制def manual_adjust(self, cipher_char, plain_char):
"""手动调整字符映射"""
if cipher_char in self.mapping:
old_char = self.mapping[cipher_char]
# 交换原有映射
for k, v in self.mapping.items():
if v == plain_char:
self.mapping[k] = old_char
self.mapping[cipher_char] = plain_char
4. 完整破译流程演示
4.1 准备测试密文
我们使用一段经典密文作为示例:
code复制"Zpy'x zpv mpv npv epv lpv gpv opv. Zp zywo zpy'x ypp npv epv lpv gpv opv."
4.2 执行破译步骤
python复制# 初始化破译器
breaker = CipherBreaker(ciphertext)
# 自动分析频率
breaker.analyze_frequency()
print("字符频率统计:")
print(breaker.freq)
# 建立初始映射
breaker.build_mapping()
print("初始映射关系:")
print(breaker.mapping)
# 生成初步解密结果
plaintext = breaker.decrypt()
print("初步解密:")
print(plaintext)
# 人工修正明显错误
breaker.manual_adjust('p', 'h')
breaker.manual_adjust('v', 'e')
print("修正后解密:")
print(breaker.decrypt())
4.3 结果验证
经过几次调整后,我们得到最终明文:
code复制"Don't do the he he he he he. Do what don't do the he he he he."
虽然语义不完整,但已经能看出原始文本的大致结构。这说明我们的破译方向是正确的。
5. 进阶优化技巧
5.1 双字母频率分析
除了单字母频率,英语中常见的双字母组合(th, he, in等)也能提供重要线索:
python复制def analyze_bigrams(self):
"""统计双字母组合频率"""
bigrams = zip(self.ciphertext[:-1], self.ciphertext[1:])
counter = collections.Counter(
(a+b for a,b in bigrams if a.isalpha() and b.isalpha())
)
total = sum(counter.values())
return {bg: cnt/total for bg, cnt in counter.most_common(10)}
5.2 字典辅助验证
引入常用词字典提高匹配准确率:
python复制def validate_with_dict(self, candidate):
"""用字典验证解密结果的可信度"""
words = candidate.split()
known_words = set(line.strip() for line in open('dict.txt'))
return sum(1 for w in words if w in known_words) / len(words)
5.3 多语言支持扩展
通过加载不同语言包实现国际化:
python复制def load_language_pack(self, lang):
"""加载语言特征包"""
lang_packs = {
'fr': {'e':15.0, 'a':8.2, 'i':7.6, 's':7.5, 'n':7.2},
'de': {'e':16.9, 'n':10.5, 'i':8.2, 's':7.2, 'r':6.9}
}
self.lang_profile = lang_packs.get(lang, {})
6. 实战注意事项
-
密文长度要求:至少需要100个字符才能获得可靠的统计结果,短文本建议结合其他线索
-
非字母字符处理:保留标点符号和空格有助于识别单词边界,但需要先过滤掉非字母字符再做统计
-
大小写统一:预处理阶段应将所有字符转为统一大小写,避免统计偏差
-
验证循环:每调整3-5个字符映射后就应该检查中间结果,避免错误累积
-
备选方案:当频率分析法失效时(如故意打乱的密文),可以尝试暴力穷举所有可能映射
我在实际测试中发现一个有趣现象:当密文中包含大量专有名词时,标准频率表会失效。这时需要先识别并排除这些非常用词,或者改用基于上下文的自适应分析方法。
