汉明码属于一种具备纠错功能的线性分组码。
线性分组码,是将信息序列按特定长度分组(设长度为\(k\)),每组信息位会相应生成一组由信息位与监督位共同构成的码字(设长度为\(n\),且\(n > k\)),各码字之间遵循线性关系。汉明码的纠错能力使其能够识别并修正传输、存储环节里出现的错误。
在数据传输时,受外界干扰影响,单个比特可能产生差错。汉明码借助添加的冗余监督位,依照特定规则精准判断出错比特位,进而完成纠正,确保信息恢复如初,宛如给数据披上一层“防护甲”,使其即便处于复杂环境,也能维持精准可靠,在通信、存储等众多领域发挥关键作用。
三重码
所谓“三重码”,恰如其字面含义,即重要之事重复三遍。就数据而言,一旦出现数据损坏状况,便可利用其他相关数据修复受损数据。只要出错数量在1个以内,对应的数据便可成功修复。
原始数据 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
发送数据 | 000 | 000 | 000 | 000 | 111 | 111 | 111 | 111 |
接收数据 | 000 | 001 | 010 | 100 | 111 | 110 | 101 | 011 |
还原数据 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
不过,要是出错地方超过2个,就无法修复了(尽管这种概率极低):
原始数据 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
发送数据 | 000 | 000 | 000 | 000 | 111 | 111 | 111 | 111 |
接收数据 | 011 | 101 | 110 | 111 | 100 | 010 | 001 | 000 |
还原数据 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
但数据出错概率很低,使用三重码需传输三次原始数据,致使传输效率下滑。既然如此,也可适当降低纠错频率。
奇偶校验码
奇偶校验码的工作原理是统计一段二进制数里“1”出现的频次。若这段数中“1”的数量为偶数,校验码是“0”;若为奇数,校验码则是“1”。以下是一个8位的简单示例:
原始数据 | 接收数据 | 校验码 |
---|---|---|
0100 1010 | 0100 1010 | 1 |
0100 1010 | 0100 1000 | 1 |
在原始数据“0100 1010”中,“1”出现了3次(奇数),所以校验码为“1” 。但在第二个数据里,接收数据“0100 1000”中“1”仅出现2次(偶数),校验码本该是“0”,实际接收的却是“1”,由此可判断该数据有误。
不过,奇偶校验码仅能判断1个以内的错误。因为它仅能体现“1”出现次数的奇偶性,一旦出现2个错误,奇偶校验码就失效了。
依据奇偶校验码特性,还能通过行列定位错误位置。下面是一个16位的例子:
实际数据 | 校验码 | ||||
---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 1 | 0 | 0 | |
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 1 | |
校验码 | 0 | 0 | 1 | 0 |
错误数据 | 校验码 | ||||
---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 0 | |
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 1 | |
校验码 | 0 | 0 | 1 | 0 |
如此,能迅速锁定出错位置。但要是出现2个连续的错误,就没办法定位了:
错误数据 | 校验码 | ||||
---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 0 | 1 | 0 | |
0 | 1 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 1 | |
校验码 | 0 | 0 | 1 | 0 |
由于每行校验码均无误,所以难以定位。而且这种方式效率不高,16位数据需8个校验码。于是,查德·卫斯里·汉明发明了——汉明码。
汉明码
有一道知名智力谜题:16杯水中有1杯有毒,怎样用最少的化验次数找出有毒的那杯?
解题思路如下:随机选8杯化验,若有毒,有毒杯子就在这8杯里;若没毒,有毒杯子就在另外8杯之中。接着选4杯化验……如此这般化验4次,直至确定有毒的那一杯。概括来讲,就是错误若不在这一半,那必然在另一半。我们继续用16位数据举例:
原始数据 | 校验码 |
---|---|
0100 1010 0100 1000 | 0 |
0100 1010 0100 1000 | 1 |
0100 1010 0100 1000 | 1 |
0100 1010 0100 1000 | 0 |
据此算出“0100 1010 0100 1000”的4位校验码是“0110”。
要是接收数据是“0100 1000 0100 1000”,其校验码是“0000”,与接收的校验码“0110”不匹配,表明接收数据有误。
第1个和第4个校验码无误,说明错误不在这些地方:
0100 1000 0100 1000
第2个和第3个校验码出错,意味着错误同时出现在第2个和第3个校验的位置:
0100 1000 0100 1000
综合上述分析,错误只会在:
0100 1000 0100 1000
所以,正确的数据应为:
0100 1010 0100 1000
然而,这种操作存在一个问题:第1位发生的错误无法检测出来。也就是说,4位校验码能够校验15位数据。此外,还面临一个难题:要是数据没错,但校验码出错,该如何处理?汉明的办法是把校验码与原始数据混合在一起:在11位数据中混入4位校验码。
位置 | 位置的2进制值 | 值 | 备注 |
---|---|---|---|
1 | 0001 | 留空 | |
2 | 0010 | 留空 | |
3 | 0011 | 0 | |
4 | 0100 | 留空 | |
5 | 0101 | 1 | |
6 | 0110 | 0 | |
7 | 0111 | 0 | |
8 | 1000 | 留空 | |
9 | 1001 | 1 | |
10 | 1010 | 0 | |
11 | 1011 | 1 | |
12 | 1100 | 0 | |
13 | 1101 | 0 | |
14 | 1110 | 1 | |
15 | 1111 | 0 |
可以发现,留空位置的二进制值仅有1位是“1”。
计算校验码时,先算出位置二进制值第1位是“1”的奇偶校验码,例如位置“1001”、“1010”,填入第8位;接着算第2位是“1”的奇偶校验码,像位置“0101”、“1110”,填入第4位;再算第3位是“1”的奇偶校验码,如位置“0110”、“1010”,填入第2位;最后算第4位是“1”的奇偶校验码,比如位置“1001”、“1011”,填入第1位。
最终,我们会得到:
位置 | 位置的2进制值 | 值 | 备注 |
---|---|---|---|
1 | 0001 | 1 | 留空 |
2 | 0010 | 0 | 留空 |
3 | 0011 | 0 | |
4 | 0100 | 0 | 留空 |
5 | 0101 | 1 | |
6 | 0110 | 0 | |
7 | 0111 | 0 | |
8 | 1000 | 1 | 留空 |
9 | 1001 | 1 | |
10 | 1010 | 0 | |
11 | 1011 | 1 | |
12 | 1100 | 0 | |
13 | 1101 | 0 | |
14 | 1110 | 1 | |
15 | 1111 | 0 |
要是第5位出错,第1位和第4位校验码会出错。从排列方式可知,要是数据出错,必然导致2个及以上校验码出错,因为数据位置的二进制值不止有1个“1”。若仅有1个校验码出错,那只能是校验码自身有问题。按上述方式,汉明码可纠正1位错误。那出现2位错误呢?可以设置第0位数来表示后面15位数的奇偶校验码:
0100 0100 1101 0010
当后面数据出现1位错误时,第0位能察觉;出现2位错误时,第0位察觉不出,但校验码能发现;如此,汉明码便拥有了纠正1位错误、察觉2位错误的能力。出现2位错误时,虽无法纠正,但能让对方重发消息来纠错。
要是出现三个错误呢?汉明码就检测不出来了。
标签:奇偶校验,错误,0100,笔记,校验码,学习,1010,汉明码,1000 From: https://www.cnblogs.com/autext/p/18637885/hamming_code