海明码又称为汉明码,英文名Hamming Code。是差错控制中的纠错码。
海明码是在原数据中的一些固定位置,插入一位奇(或偶)校验位,虽然使原数据变长,但可使其拥有纠错能力。
能侦测并更正一个比特的错误;若有两个比特出错,则只能侦测,不能更正;若有三个或更多的比特出错,则不能侦测,更不能更正。
以二进制串10110为例,以偶校验将其编码为海明码。
生成的海明码中,位置为2的幂位均为校验位,用表格表示如下:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
位置为2的幂 | 2^0 | 2^1 | 2^2 | 2^3 | 2^4 |
除去校验位,全部都是数据位。
在第1步的表格中,我们标出数据位:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
是否为2的幂 | 2^0 | 2^1 | 数据 | 2^2 | 数据 | 数据 | 数据 | 2^3 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 2^4 | 数据 |
将例子中的数据(二进制串10110)填入海明码。同时,为了方便识别,我们将校验位标为R,数据位标为D,即R1、R2、R4、R8、R16……,为校验位;D3、D5、D6、D7、D9……,为数据位。
继续完善表格:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
是否为2的幂 | 2^0 | 2^1 | 数据 | 2^2 | 数据 | 数据 | 数据 | 2^3 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 2^4 | 数据 |
所在位的标识 | R1 | R2 | D3 | R4 | D5 | D6 | D7 | R8 | D9 | D10 | D11 | D12 | D13 | D14 | D15 | R16 | D17 |
海明码的值 | 1 | 0 | 1 | 1 | 0 |
通过偶校验算出海明码中校验位的值,下表显示了各校验位的值如何计算:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
所在位的标识 | R1 | R2 | D3 | R4 | D5 | D6 | D7 | R8 | D9 | D10 | D11 | D12 | D13 | D14 | D15 | R16 | D17 |
参与R1校验 | X | X | X | X | X | X | X | X | X | ||||||||
参与R2校验 | X | X | X | X | X | X | X | X | |||||||||
参与R4校验 | X | X | X | X | X | X | X | X | |||||||||
参与R8校验 | X | X | X | X | X | X | X | X | |||||||||
参与R16校验 | X | X |
具体的计算规律如下:
位置为Rx的检验位,是从第x位开始(即从Rx开始),检验x位,跳过x位,再检验x位,在跳过x位,以此类推。
例如上表中,位置为R4的检验位,是从第4位开始(即从R4开始),检验4位(检验4、5、6、7共4位),跳过4位(跳过8、9、10、11共4位),检验4位(检验12、13、14、15共4位),以此类推。
最后,根据第4步计算出校验位的值并填入,就能得到海明码了,计算过程如下:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
是否为2的幂 | 2^0 | 2^1 | 数据 | 2^2 | 数据 | 数据 | 数据 | 2^3 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 2^4 | 数据 |
所在位的标识 | R1 | R2 | D3 | R4 | D5 | D6 | D7 | R8 | D9 | D10 | D11 | D12 | D13 | D14 | D15 | R16 | D17 |
海明码的值 | R1 | R2 | 1 | R4 | 0 | 1 | 1 | R8 | 0 | R16 |
R1 = 偶校验(R1, 1, 0, 1, 0) = 0
R2 = 偶校验(R2, 1, 1, 1) = 1
R4 = 偶校验(R4, 0, 1, 1) = 0
R8 = 偶校验(R8, 0) = 0
R16 = 数据太短,当用到D17位置时,才需要R16
将计算结果填入表中:
海明码中的位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
是否为2的幂 | 2^0 | 2^1 | 数据 | 2^2 | 数据 | 数据 | 数据 | 2^3 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 数据 | 2^4 | 数据 |
所在位的标识 | R1 | R2 | D3 | R4 | D5 | D6 | D7 | R8 | D9 | D10 | D11 | D12 | D13 | D14 | D15 | R16 | D17 |
所在位的值 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
得到的海明码为“0110 0110 0”。
首先,按照编码的方式(奇校验或偶校验),依次检测校验位R1、R2、R4、R8……,然后,将出错的校验位的位置相加,比如发现R1、R8出现错误,则将1和8相加,得到9,即为位置D9的比特出错,最后,将该错误的比特取反就能更正错误。
假设编码示例中生成的海明码“0110 0110 0”,在传输中出错,最后一位(标识D9)出错,错误的海明码为“0110 0110 1”
该海明码使用教研方式是偶校验,所以我们检验校验位时,也要使用偶校验。
R1 = 偶校验(R1, 1, 0, 1, 0) = 0,出错
R2 = 偶校验(R2, 1, 1, 1) = 1,正确
R4 = 偶校验(R4, 0, 1, 1) = 0,正确
R8 = 偶校验(R8, 0) = 0,出错
将出错的校验位的位置相加:
出错比特的位置 = R1的位置是1 + R8的位置是8 = 9
将第9位取反,就能更正错误。
错误的海明码为“0110 0110 1”,更正第9位后为“0110 0110 0”。