想象你在寄一封重要的信。信件在运输过程中可能会因为颠簸而弄脏某个字。
如果你只是写了一句话,弄脏一个字后,你可能完全看不懂原意。
但如果你用了一种巧妙的方式多写几个字,收信人不仅能发现哪个字被弄脏了,还能自动把它改正过来!
在计算机世界里,数据在传输过程中也可能因为电磁干扰等原因发生"翻转"——一个 0 变成了 1,或者一个 1 变成了 0。
奇偶校验
在数据末尾加一个"校验位",使得所有位中 1 的个数为偶数。
1 0 1 1
→ 有 3 个 1(奇数)
1
→ 凑成 4 个 1(偶数)
1 0 1 1 1
✅ 如果收到 1 0 0 1 1,发现 1 的个数变成奇数 → 有错!
❌ 但到底是哪一位错了?不知道,无法纠正。
海明码
使用多个校验位,每个校验位负责检查不同的数据位组合。
当出错时,通过分析哪些校验位"报警",就能精确定位出错的那一位!
✅ 能检测错误
✅ 能定位错误在哪一位
✅ 能自动纠正那一位错误
海明码把每一位分成两种角色:
数据位 (Data Bits)
就是你要传输的原始信息。比如 4 位数据 1 0 1 1。
校验位 (Parity Bits)
额外添加的"哨兵"。每个校验位负责监视一组特定的位置。
关键规则:校验位住在"2 的幂次"位置
想象海明码是一排编号的格子,每个格子放一个 0 或 1。格子的编号从 1 开始(不是从 0 开始,这点很重要)。
规则很简单:编号是 2 的幂次(1, 2, 4, 8…)的格子留给校验位 P,其余格子放数据位 D。
以 4 位数据为例,需要 7 个格子(3 个校验位 + 4 个数据位):
每个校验位"管"哪些位置?
这是海明码最精妙的地方。把位置编号(注意:是编号,不是数据值)写成二进制,就能看出每个校验位负责"监视"哪些格子:
- P₁(位置 1 = 二进制
001):管所有二进制末位为 1 的位置 → 1, 3, 5, 7 - P₂(位置 2 = 二进制
010):管所有二进制倒数第二位为 1 的位置 → 2, 3, 6, 7 - P₃(位置 4 = 二进制
100):管所有二进制第三位为 1 的位置 → 4, 5, 6, 7
下面的表格验证了这一点。"位置编号的二进制"这一列只是把左边的位置编号(1~7)转换成 3 位二进制数,跟数据内容无关。表中 P₁、P₂、P₃ 表示该位置是该校验位自己的"家",✓ 表示该位置也被这个校验位管辖:
| 位置编号 | 编号转二进制 | P₁ 管辖 | P₂ 管辖 | P₃ 管辖 |
|---|---|---|---|---|
| 1 | 0 0 1 | P₁(自己) | ||
| 2 | 0 1 0 | P₂(自己) | ||
| 3 | 0 1 1 | ✓ 被P₁管 | P₂(自己) | |
| 4 | 1 0 0 | P₃(自己) | ||
| 5 | 1 0 1 | ✓ 被P₁管 | P₃(自己) | |
| 6 | 1 1 0 | ✓ 被P₂管 | P₃(自己) | |
| 7 | 1 1 1 | ✓ 被P₁管 | ✓ 被P₂管 | P₃(自己) |
111,三个校验位都管它;位置 5 = 101,P₁ 和 P₃ 管它。这些管辖关系在下一章计算校验位时会直接用到。
我们用 4 位数据来实际操作一遍。你可以修改下面的数据位(点击格子翻转),然后跟着步骤计算校验位。
现在来体验海明码最神奇的部分——自动发现并纠正错误!
下面是刚才编码得到的 7 位海明码。点击"模拟传输"按钮,计算机会随机翻转其中一位来模拟传输错误。
输入 4 位数据(点击格子翻转),实时查看编码过程和结果。
输入 7 位海明码(点击格子翻转),自动检测并纠正错误。
计算机会随机生成一道题:发送一个海明码并制造一个错误。你的任务是找出出错的位置!