在之前的研究中,我们使用 “已知明文 crib” 暴力破解 Enigma 密文。但如果没有 crib—— 比如拦截了一段完全未知的通信 —— 还能破解吗?答案是肯定的,只需利用语言本身的统计特征。William Friedman 于 1922 年发明了重合指数(Index of Coincidence,简称 IC),它不需要已知明文,只凭密文的统计指纹就能推断加密设置。本文详解在 Commodore 64 上实现 IC 破解 Enigma 的完整工程参数。

重合指数原理

从一段英文文本中随机抽取两个字母,它们相同的概率是多少?由于字母频率非均匀分布(E 出现约 13%,Z 少于 0.1%),这个概率高于随机猜测。对于英文文本,IC 约为 0.0667;德文类似,约 0.0762;而真正的随机文本(26 个字母等概率)为 1/26 ≈ 0.0385。这个差异就是攻击的核心:用错误设置解密的输出呈现随机分布,IC 接近 0.038;用正确设置解密才能得到德语文本,IC 接近 0.067。

IC 的计算公式为:$IC = \frac {\sum_{i=0}^{25} n_i \cdot (n_i - 1)}{N \cdot (N - 1)}$,其中 $n_i$ 是字母 i 出现的次数,N 是文本总长度。在 C64 上实现时,根本不需要浮点除法 —— 只需计算分子 IC sum = $\sum n_i \cdot (n_i - 1)$,然后与阈值比较即可。对于 60 字符消息,IC >= 0.050 对应 IC sum >= 177(计算方式:0.050 × 60 × 59 = 177)。这个阈值对应 16 位整数比较,不需要浮点运算。

插线板的免疫性

这可能是 IC 方法最优雅的特性:插线板(Steckerbrett)对 IC 完全透明。插线板本质上是单表替换 —— 如果 R 和 M 互换,输出中每个 R 变成 M,每个 M 变成 R,但每种字母的总数不变。IC 只关心最频繁字母的频率分布,不关心具体是哪个字母。插线板只是给频率分布的 “箱子” 贴了新标签,箱子大小不变。这意味着 IC 攻击只需破解转子设置(5.9 百万种组合),插线板可以单独用频率分析解决。

实战参数:60 字符消息

我们截获了一段 60 字符的 Enigma 密文,不知道任何明文信息。正确设置仍是转子 III-I-V,位置 M-C-Q(对应 “WETTERVORHERSAGEBISKAYAHEUTEREGENMITWINDSTAERKEFUENFAUSOSTEN”,这是一条标准 U 艇天气报告)。使用不同阈值的筛选效果如下:

阈值 IC Sum 候选数 占比
0.040 141 6,233 35.5%
0.045 159 1,540 8.8%
0.050 177 286 1.6%
0.055 194 49 0.3%
0.060 212 7 0.04%

对于单个转子顺序(III-I-V),阈值 177 产生 286 个候选;正确答案是第 146 个输出,IC sum 258。阈值 194 收紧到 49 个候选,正确答案排名 #42。关键发现:仅凭 IC 分数无法直接定位正确答案,因为随机字母分布偶尔会碰巧产生高分。只有阅读解密文本才能从候选中挑出真正的德语。

6502 汇编实现参数

核心 IC 测试循环结构如下:清除 26 字节频率表 → 设置起始转子位置 → 解密全部 60 字符并累计频率 → 计算 IC sum(16 位累加器)→ 与阈值比较。阈值 194(IC >= 0.055)用于全量搜索所有 336 种转子顺序;阈值 177(IC >= 0.050)用于单顺序搜索。IC sum 最大值 60×59=3540,完全在 16 位范围内。频率计数使用间接寻址递增:每次解密后,结果作为索引直接递增 freq,x。

乘法部分采用重复加法,因为频率最大值约 10(60 字符中某字母最多出现 10 次),循环次数有限。16 位比较先检查高位字节,非零则通过;高位为零时才比较低位字节。

性能数据

全量搜索 5,905,536 种候选(336 转子顺序 × 17,576 位置)的实测数据:每候选需要解密全部 60 字符(60 次完整加密,每次约 720 周期),加上频率计数和 IC 求和。使用 BASIC 解释器搜索单转子顺序约需数小时;6502 汇编版本在 NTSC C64(1.022727 MHz)上需要 82 小时。优化 rotorpass 内联 mod26 后降至 67 小时 21 分钟 —— 仅因移除两个 jsr/rts 调用就获得 18% 加速。

正确答案出现在第 87 个转子顺序,约 21 小时后出现在打印机输出中。其余 61 小时只是确认其他顺序没有更好候选。

与明文攻击的对比

有 crib 时使用暴力破解,每个候选只需约 1 次加密(首字符不匹配即退出),总耗时约 22 分钟。IC 攻击则需要 60 次加密加上统计计算,速度慢 2000 倍左右,但换来了无需任何先验知识的普适性。这是密码学中经典的速度与通用性权衡。

在现代硬件上,同一算法在 Apple M4 单核需 1.856 秒,全核 OpenMP 需 0.409 秒,Metal GPU 只需 0.039 秒 —— 比 C64 快 750 万倍。但核心数学完全相同:统计语言特征,无须破解者具备先验信息。

工程建议

实际部署时建议连接打印机(OPEN 4,4:CMD 4:SYS 49152),因为搜索耗时数天,屏幕会滚动覆盖所有输出。阈值选择应根据消息长度调整:60 字符建议 177-194;200 + 字符可使用更高阈值(因为 IC 更稳定);短消息需要更宽松阈值配合人工筛选。找到正确转子设置后,插线板可通过比较解密文本与标准德语字母频率单独求解,这是 Friedman 方法的标准两阶段流程。

资料来源:Imapenguin.com 2026 年 3 月 31 日文章,GitHub 仓库 mrdoornbos/enigma_ic 包含完整代码。