背景介绍
由Richard Hamming于1950年提出、还被广泛采用的一种很有效的校验方法,是只要增加少数几个校验位,就能检测出二位同时出错、亦能检测出一位出错并能自动恢复该出错位的正确值的有效手段,后者被称为自动纠错。它的实现原理,是在k个数据位之外加上r个校验位,从而形成一个k+r位的新的码字,使新的码字的码距比较均匀地拉大。把数据的每一个二进制位分配在几个不同的偶校验位的组合中,当某一位出错后,就会引起相关的几个校验位的值发生变化,这不但可以发现出错,还能指出是哪一位出错,为进一步自动纠错提供了依据。(来自百度百科)
简单来说就是可以校验并纠错。
信息位和校验位
海明的校验位在2n上,即校验码在第1,2,4,8位,其余位是信息位,如果信息位数量位K,校验位数量位r,他们满足一下关系:
2r >= K + r + 1
直观的显示:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | ||
|---|---|---|---|---|---|---|---|---|
| 信息位 | … | I4 | I3 | I2 | I1 | |||
| 校验位 | … | r3 | r2 | r1 |
校验位的算法
规则:一个信息位由他之前的校验位来校验,且满足信息位位置=校验位位置之和 即:信息位3 = 校验位2 + 校验位1
列举一些信息位和校验位的关系:
| 数据位 | 校验位 | 备注 |
|---|---|---|
| 1 | - | 校验位 |
| 2 | - | 校验位 |
| 3 | 1 + 2 | |
| 4 | - | 校验位 |
| 5 | 4 +1 | |
| 6 | 4+2 | |
| 7 | 4+2+1 | |
| 8 | - | 校验位 |
因此, 校验位就由它相关的信息位生成,且规定信息位依次异或得到校验位。列举一些校验位计算公式:
| 校验位 | 公式 | 说明 |
|---|---|---|
| 1 | 3⨁5⨁7 | 见上表,3 5 7 都有使用校验位1;3、5、7表示数据位置 |
| 2 | 3⨁6⨁7 | 同理 |
| 3 | 5⨁6⨁7 | 同理 |
| … |
举例计算
根据规则计算ob1011的海明校验码。
确定校验位位数:
根据公式:
2^r^ >= K + r + 1,且已知K=4(因为要计算的原数据为0b1011),从r = 1开始,使用枚举法依次递增取值,计算出第一个符合条件的r值。当然, 根据上面的经验,我们很容易得出r=3的结论。画图标定各数据位的值
位 8 7 6 5 4 3 2 1 信息位 1 0 1 1 校验位 r3 r2 r1 根据信息位计算校验位
r1 = 3⨁5⨁7
r2 = 3⨁6⨁7
r3 = 5⨁6⨁7
上面的数字表示数据位下标
r1 = 1⨁1⨁1 = 1
r2 = 1⨁0⨁1 = 0
r3 = 1⨁0⨁1 = 0
获取到最终数据
位 8 7 6 5 4 3 2 1 信息位 1 0 1 1 校验位 0 0 1 终值 1 0 1 0 1 0 1
纠错
如果传输工程中发生了错误,如:1010101 --> 1000101
将接收到的值取出信息位和校验位:
位 8 7 6 5 4 3 2 1 信息位 1 0 0 1 校验位 0 0 1 根据接收的信息位计算出校验位:
r1 = 3⨁5⨁7
r2 = 3⨁6⨁7
r3 = 5⨁6⨁7
r1 = 1⨁0⨁1 = 0
r2 = 1⨁0⨁1 = 0
r3 = 0⨁0⨁1 = 1
将接收信息计算的校验位和接收到的校验位按位异或:
001⨁100 = 101
将上一步计算结果转为10进制,即为错误位数
0b101 = 5
将错误位取反,即可获取到正确的数据
位 8 7 6 5 4 3 2 1 信息位 1 0 0->11 校验位 0 0 1 终值 1 0 1 0 1 0 1 读数:1010101
成功取得正确数据。