Skip to content

海明码详解

2026 大纲的「二、数据的表示和运算」与「三、存储器层次结构」均已不含校验码,本篇不对应任何条目编号;但纠错编码在 408 计算机网络「三(三)差错控制」 中仍是纲内内容,海明码正属此列。内存 ECC 用的就是它的 SEC-DED 变体。

怎么分配时间:备考 CN 差错控制的按纲内内容读;只复习 CO 的把编码与纠错的流程走一遍即可,不必做题训练

让每一位留下互不相同的"指纹"

奇偶校验只能告诉你"有错",因为整个码字只归入一个校验组,失配时无从分辨是哪一位坏了。海明码的做法是:

🔴 把每一位分配到多个校验组里,且每一位所属组的组合各不相同。 某一位出错时,包含它的那些组全部失配、不含它的组不受影响——这个失配模式就是这一位的"指纹"。再把指纹设计成"位编号的二进制",读出失配模式就直接读出了出错的位置。

这一句话解释了海明码的每一处设计。三条最容易被当成"规定"来背的,其实都是它的必然推论:

🔴 位编号从 1 开始,不是从 0。 编号 0 的二进制是全 0、不属于任何校验组,出错时故障字仍为 0,与"无错"无法区分。全 0 这个状态必须留给无错。

🔴 校验位必须占 2j 号位(1、2、4、8……)。 只有这些编号的二进制只含一个 1,即各自只属于一个组。校验位 P2j 由第 j 组其余成员算出;若它同时还属于别的组,算 P1 要用 P2、算 P2 又要用 P1互相依赖就解不出来了

🔴 分组规则位编号的二进制第 j 位为 1,该位就归入第 j(由 P2j 校验)。数据位填进剩下那些编号(3、5、6、7、9……),它们含两个及以上的 1、因而横跨多个组——这正是"让指纹互不相同"所需要的。

交互可视化

加载可视化中...

一、校验位数量:2rk+r+1

r 个校验组的失配情况拼成一个 r 位的故障字(也叫校验和),它一共能表达 2r 种状态。这些状态必须够用:

n每一位各占一种状态+1“无错”也要占一种2r
数据位 k校验位 r总码长 n
123
437
8412
16521
32638
64771

k=8 为例:r=323=8<8+3+1=12,不够;r=424=168+4+1=13,成立。所以取 r=4

🔴 r 在不等式两边都出现,不能直接解,只能从小到大逐个试。 好在 r 增大时左边指数增长、右边线性增长,第一个成立的就是答案

🔴 那个 +1 不能省。 它是"无错"状态的名额,通常约定用全 0 的故障字表示。省掉的话 2r 个状态刚好被 n 个出错位占满,接收端就无法表达"什么都没错"。

二、位置与分组

n 位码字从左到右编号为 1,2,3,,n,以 7 位码字为例:

编号二进制属于哪些组
1001P1
2010P2
3011P1,P2
4100P4
5101P1,P4
6110P2,P4
7111P1,P2,P4

于是三个校验组分别是

P1:{1,3,5,7}P2:{2,3,6,7}P4:{4,5,6,7}

对每组做偶校验,由于每组只含一个校验位,直接令它等于组内其余各位的异或:

P1=b3b5b7,P2=b3b6b7,P4=b5b6b7

三、故障字为什么直接等于出错位编号

接收端对每一组连同校验位一起重新做偶校验,把结果记为 Sj(相符为 0,失配为 1),拼成故障字 S=S4S2S1(高位在左)。

i 位参与的组,恰好是 i 的二进制中为 1 的那几位对应的组(这正是分组规则)。第 i 位翻转时,这些组全部由偶变奇Sj=1),其余组不含它、丝毫不受影响Sj=0)。于是 S 的第 j 位为 1 i 的第 j 位为 1,即

S=i

没有出错时所有组都相符,S=0——这正是那个 +1 预留的状态。

编码与纠错各走一遍:从数据位填格到故障字定位(想核对自己算校验位、算故障字的每一步时展开)

编码。 k=4,数据 D1D2D3D4=1001,依次填入编号 3、5、6、7 号位。

编号1234567
内容P1P2D1P4D2D3D4
??1?001

逐个算:

P1=b3b5b7=101=0P2=b3b6b7=101=0P4=b5b6b7=001=1

码字(编号 1→7)= 0011001 自查:P1{0,1,0,1} 两个 1,偶 ✓;P2{0,1,0,1} 偶 ✓;P4{1,0,0,1} 偶 ✓。

纠错。 发送 0011001,传输中第 5 位由 0 翻成 1,接收到 0011101

成员编号收到的值异或Sj
P11, 3, 5, 70, 1, 1, 111
P22, 3, 6, 70, 1, 0, 100
P44, 5, 6, 71, 1, 0, 111
S=S4S2S1=1012=5

第 5 位出错,把它翻回去即得 0011001,与发送的一致。海明码的全部工作量都在分组的设计上,运行时开销极小——这正是它能被做进内存 ECC 硬件的原因。

四、SEC-DED:再加一位换来"且"

标准海明码 d=3,按 校验码总述 里的公式只能"纠 1 检 2"。SEC-DED(Single Error Correction, Double Error Detection)再加一个校验位 P0覆盖全部位(包括其他所有校验位),对整个码字做一次偶校验。最小码距增大到 d=4,满足 de+t+1=2+1+1,于是可以同时"检 2 纠 1"。

判别逻辑变成两个信号的组合:

P0 校验故障字 S结论
相符=0无错
失配01 位错,位置为 S,可纠正
相符02 位错,只能报错,无法定位
失配=0P0 自身出错

判据来自奇偶性:错 1 位时全局 1 的个数奇偶性改变(P0 失配),错 2 位时奇偶性不变(P0 相符)——而故障字 S 在两种情况下都非零。两个信号一组合,就把"1 位错"和"2 位错"区分开了。

考点速记

  1. 海明码把每一位分配到若干个校验组中,让每一位所属组的组合互不相同,失配模式即"指纹";校验位数量满足 2rk+r+1+1 是"无错"状态的名额r 只能从小到大逐个试。
  2. 位编号从 1 开始校验位放在 20,21,22, 号位,因为这些编号的二进制只含一个 1、每个校验位只属于一组r 个校验位才能彼此独立算出。分组规则是"位编号二进制第 j 位为 1 则归入第 j 组"。
  3. 纠错时各组重新校验得故障字,它直接等于出错位的码字编号,全 0 表示无错;标准海明码 d=3 只能"纠 1 位检 2 位",SEC-DED 再加一位覆盖全码字的 P0 使 d=4

这一节在真题里被考过的形式(下方「真题练习」里那道就是本篇的):

  • 给数据位数,问纠一位错至少需要几位校验位:套 2rk+r+1 逐个试 r。8 位数据:r=38<12 不够,r=41613 成立,答 4。⚠️ 两处常错——把 +1 漏掉,或者拿 2rk 去算(那样 8 位数据会得出 3,正是准备好的错误选项)。

易错:漏掉不等式里的 +1。它是"无错"状态的名额。

易错:把 2rk+r+1 当成可以直接解的方程。r 在两边都有,只能逐个试。

易错:把故障字 S 当成数据位的序号。S 给的是码字位编号——7 位海明码里 1、2、4 是校验位,3、5、6、7 才是 D1D4,所以 S=5 对应的是 D2。校验位自己出错时故障字同样非零(S 是 1、2 或 4),这种情况数据其实完好。

易错:认为海明码能纠 2 位错。d=3 只支持 t=1;发生 2 位错时故障字通常非零,但它指向的是第三个无关的位置,按它去"纠正"反而把数据改得更错——这正是 SEC-DED 存在的理由。

教材出处
  • 汉明码的一位纠错能力、检测位数满足 2kn+k+1、代码长度与检测位位数的关系表(表 4.2)、检测位安插在第 1,2,4,8,,2k1 位上及各小组的划分(g1 含 1,3,5,7…,g2 含 2,3,6,7…,g3 含 4,5,6,7…):唐朔飞《计算机组成原理》第 3 版 第 4 章 存储器·汉明码,印刷页 p100–p101
  • 纠错过程:接收后重新形成检测位 Pi,由 Pi 的状态直接指出错误位置:同书,印刷页 p101

相关知识

校验码总述:码距、奇偶校验与 CRC|计算机网络博客的海明码

真题练习

相关真题(1题)