欢迎大家去作者本人的B站的频道,观看相同的内容
https://www.bilibili.com/read/cv15301611
PS:本人学生一名,自学,没有项目经验,可能对程序的理解有误,有问题欢迎提出。
什么是汉明码
百度百科:汉明码(Hamming Code),是在电信领域的一种线性调试码,以发明者理查德·卫斯里·汉明的名字命名。汉明码在传输的消息流中插入验证码,当计算机存储或移动数据时,可能会产生数据位错误,以侦测并更正单一比特错误。由于汉明编码简单,它们被广泛应用于内存(RAM)。
白话:是一种判断数据是否错误,若错误即更正过来的纠错码1。用来保证数据传输的准确性。
我们可以从生活中看到很多这样的例子。比如被轻微损坏的光盘,我们可以通过这个例子就可以明白纠错码的工作过程,如下。
步骤 | 例子 | 程序 |
---|---|---|
第1步 | 拿出光盘 | 获取需要发送的数据 |
第2步 | 把光盘放到光盘播放器并开始播放 | 进行数据的连接并开始读取数据 |
第3步 | 正常播放 | 读取数据,并使用纠错码,防止数据出错 |
而中间这个纠错码就是我们讨论的内容,因为纠错码的类型很多,这里就只说明经典的汉明码。OK,说了这么久,让我们来正式开始我们的内容。 |
汉明码的内部
汉明码利用了奇偶校验位的概念,通过增加一些比特来变成校验位。利用一个以上的校验位,汉明码不仅可以验证数据是否有效,还能在数据出错的情况下指明错误位置。
首先,先生成一个数据。
位置从0~15,总共有16个bit,但是其中有几个是校验码(0,1,2,4,8),这个校验码的位置是2n,n>-1。稍后解释这个位置的神奇之处。我们先聊聊这个校验码的运算——奇偶校验位
奇偶校验位
简单的来说奇偶校验位。就是数有多少个1。
如果有奇数个1,这校验码为1。
如果有偶数个1,这校验码为0。
假设a={1,1,0,0,1,0,1,1,1,0,1,0},这个a里总共有7个1,此时这个校验位为1。
假设a={0,0,1,0,1,0,1,1,0,1,0,1},这个a里总共有6个1,此时这个校验位为0。
假设a={0,0,0,0,1,0,1,0,1,0,0,0},这个a里总共有3个1,此时这个校验位为1。
假设a={0,0,0,0,0,0,0,0,0,0,0,0},这个a里总共有0个1,此时这个校验位为0。
可是我们应该如何将奇偶校验位和汉明码结合在一起。不急,可以听我娓娓道来。其实找出错误的数据,就像是我们在猜随机数2一样。
奇偶校验位+汉明码的例子解释
这个游戏很快的方式就是对半猜。例如0-100,我们猜50,。50-100,我们猜75.就是从它的中间数猜,这个方法是很快的。而汉明码也是一样。首先我们先竖猜一半。
PS:因为位置4,8是打横的校验位,而0是一个特殊的校验码,这个稍后说明。
PPS:为了方便理解,在这个例子我们校验位的判断顺序为1->2->4->8
- 这个黄色的框就是我们 1 判断的范围,我们这个看位置1。位置1 的值为0,说明在这个框中应该有偶数个1,但是只有位置3,7.15是1 ,其他都是0,说明这个框里有问题。注意这里不看校验位本身的值。
- 这个黄色的框就是我们 2 判断的范围,位置2的值为1,说明在这个框中应该奇数个1,但是只有位置3,6,7,10,15是1 ,其他都是0,共5个。说明这个框里没有问题。注意这里不看校验位本身的值。
Q:这个位置2 的判定为啥是这样的?
A:这样我们先假设问题在左边,然后根据上面的一半一半的去判断,那么我们要判断 1列或 2列,二选一。因为1列没有问题,则 问题在2列。同理 2列没有问题,则问题在 1列。
OK吧,然后我们将问题放在右边,同理,跟上面一样的,去判断 3列或 4列,二选一。
Q:为什么位置2的判定不能是 1,4列 呢?
A:可以看看 1,4列中包含位置 2 吗?答:没有。
其实我们可以假设下位置2 的判断真的在 1,4 列,然后问题刚好在 1,4列之中,我们可以发现位置2的值,无论怎么改变,它都不是这个整体的,它就是像是多余出来的一个数。所以位置2 的判定为 1,4列。
OK,我们停一下,我们在第一步中发现问题在左半边,在第二步我们发现第1,3列没有问题。我们做一个图来表示
红色质疑,蓝色保护。我们可以十分明显的看到 4列有一个质疑和一个保护,说明 4列没有问题,而 2列 有一个质疑没有保护,我们就可以充分地怀疑 2列。
-
这个黄色的框就是我们 4 判断的范围,位置4的值为1,说明在这个框中应该奇数个1,但是只有位置6,7,12,15是1 ,其他都是0,共4个。说明这个框里有问题。注意这里不看校验位本身的值。
-
这个黄色的框就是我们 8 判断的范围,位置8的值为1,说明在这个框中应该奇数个1,但是只有位置10,12,15是1 ,其他都是0,共3个。说明这个框里没有问题。注意这里不看校验位本身的值。
OK,到这里原本 2列有问题,即格子1,5,9,13。
∵第三步说5,13 有问题
∴问题在格子 5,13
∵第四步说格子13,9没有问题
∴问题在格子 5
以上就是这几个校验码的运算过程,看上去好像很复杂,其实多练几下是很简单的,然后就会发现它的神奇之处。下面有两道题你可以试试看。答案在最后。
题目1
题目2
到这里了,应该能将前面的内容看懂了,那我们可以讲讲几个神奇之处。
神奇之处
我们可以先看看,上面那个例子。第一步有问题,第二步没有问题,第三步有问题,第四步没有问题,我们将转化成二进制。
第四步 | 第三步 | 第二步 | 第一步 |
---|---|---|---|
0 | 1 | 0 | 1 |
二进制(0101)=十进制(5),而问题位置就在5,注意这个不是巧合,每一个位置出错都能以这种方法解决。你可以试试上两个题目,答案都是对的。因为,我们在 判断位置1 的校验码是否正确?,其实也在问错误的位置的二进制 的最后一位是不是 1。我们将位置用二进制表示,然后将最后一位为 1 高亮就会发现,很神奇的事情。这里提一下,我们通过4个是和否的问题,我们有16种可能,但是还有一种结果(没有错误)该怎么表示,很简单忽略 0 就行了。这就说明我们是对15位而不是16位的数据进行计算。11位数据,4位校验,这就是业内人士所说的(15,11)汉明码 | |||
它的位置跟判断范围一样,同理其他的校验位的判断范围也是一样的,都是跟位置中 1有关。最后两位为1 跟位置2 的判断范围 都是一样,以此类推 最后3位和最后4位,也是一样的。所以这些问题其实以二进制的方式告诉我们错误在哪里。但是它还能一种更简单的方式表现不来。异或运算。 |
提醒一下,下面的内容,有一些异或运算(xor)3,希望对运算规则要有了解才行。
- 首先先将所以位置数位上为 1 的 位置,进行异或运算。还是上面那个例子,位置2,3,4,6,7,8,10,12,15 都为1 ,将他们进行异或
大家可以猜到这个5 就是错误。其实,就是在最右一列在计算所有末尾 为1 的位置,只不过把范围定在 所以数据为1的位置 。也就是有多少数据为1 的位置来自于 位置2 的校验位的范围。同理,3和4 也是一样的。 - 而下一步,发送方负责切换检验位的值 让所得的和为 0000
因为这样 无论如何添加或删除 1 ,都能直接得到错误位置结果。大家可以动手试一试,你会发现新的天地。
Q&A
Q: 位置0 到底用来干啥?
A: 其实位置0 没啥用,但是我们可以用一种聪明的方法,让位置0 发挥一些作用 ,就是将它作为整个信息的奇偶校验位,这样就可以让我们检测到两位的错误,即使我们不用修复它。在设置 1,2,4,8 这四个校验位之后,设置位置0 来使整个数据的奇偶性为偶。
c#程序
作者在写博客,请等等,很快的,QQ
答案
题目1:错误的位置在6
题目2:错误的位置在15
欢迎大家去作者本人的B站的频道,观看相同的内容,拜托了,增加浏览量一下
https://www.bilibili.com/read/cv15301611