引言
想必看到这片文章的同学,已经对CRC校验码的生成过程和理论依据如数家珍,但是CSDN上却很少有详细讲述CRC是如何纠错的。关于CRC校验码生成的理论,前人之述备矣,我也就不赘述了,不了解的同学可以在CSDN上搜索CRC相关知识。下面以一道例题来把CRC检验的整个过程讲述一遍,重点是讲述如何纠错。
至于CRC能不能纠错,可以参见下面这两篇文章
循环冗余码CRC可不可以纠错
计组与计网数据编码之数据保证—奇偶校验,汉明码(海明码)与循环冗余码CRC以及异或的应用、看完之后做题不迷茫
例题
现在我们拥有信息位1100和生成多项式G(X)=1011,通过模2除生成校验码1100010,对此有如下表格,即不同出错位与余数的对应表,实际上计算机并不知道这个表格,这个表格是我们人为计算的得出的,计算机仅仅知道此情况下第一位出错的余数是101。
现在假设接受到的校验码是1100011,这个数与G(X)=1011作模二除结果是001,与我们发送的校验码1100010相比较,很明显最后一位出错了,我们用下划线标注上这一位。用于观察计算过程中这一位的变化情况。事实上,计算机不知道001对应哪一位出错了,计算机只知道第一位出错的余数是101(注意,文末有对这句话的解释,先搞懂整个流程怎么做的,再去探究细节原因)。
提前说明几点问题
1.纠错利用的原理是出错状态的下的余数补0后,继续与G(X)进行模二除,重复操作会产生循环。
2.循环左移是指,把校验码往左移,校验码最左边的一位移动到最右边,直观上就像是一个环庄,所以叫循环左移.
看到这里你可能还不懂,没关系,通过一个例子,你就肯定会明白了。
开始纠错
情况说明 | 校验码当前情况 | 运算 | 余数 |
---|---|---|---|
发现出错,开始纠错 | 1100011 | 1100011与G(X)模二除 | 001 |
校验码循环左移,同时余数001补0,成为0010,与G(X) 模二除 | 1000111 | 0010与G(X)模二除 | 010 |
校验码循环左移,同时余数010补0,成为0100,与G(X) 模二除 | 0001111 | 0100与G(X)模二除 | 100 |
校验码循环左移,同时余数100补0,成为1000,与G(X) 模二除 | 0011110 | 1000与G(X)模二除 | 011 |
校验码循环左移,同时余数011补0,成为0110,与G(X) 模二除 | 0111100 | 0110与G(X)模二除 | 110 |
校验码循环左移,同时余数110补0,成为1100,与G(X) 模二除 | 1111000 | 1100与G(X)模二除 | 111 |
校验码循环左移,同时余数111补0,成为1110,与G(X) 模二除 | 1110001 | 1110与G(X)模二除 | 101 |
发现当前余数位101,已知101代表第一位出错,把第一位与1进行异或运算(或取反运算),纠错 | 0110001 | 无运算 | 无 |
校验码循环左移,同时余数101补0,成为1010,与G(X) 模二除 | 1100010 | 1010与G(X)模二除 | 001 |
此时发现余数已经回到了原来的001,说明循环左移移动了一圈,同时在出错位移动到第一位的时候我们把出错位纠正了,现在原本出错的位置又回到了原来的地方,并且数据也已经更正了。结果为110010与我们的发送的原校验码一致。 |
基本思想
现在我们可以总结纠错的基本思想
- 不论出错在哪一位,均要通过出错位循环左移到最左边一位上来进行纠正。
- 不为0的余数具有循环特征,即在余数后面补上一个0后除以多项式,将得到下一个余数。继续在新余数的基础上补零除以生成多项式,重复该操作,最终余数能循环到最开始的余数,CRC由此得名。
- CRC就是利用不为0余数的循环特性,在循环计算余数的同时,将收到的CRC编码同步循环左移,当余数循环到等于最左边位出错对应的余数时,表明出错位已经移到了CRC码的最左边,对出错位进行纠错
- 继续进行余数的循环计算,并同步移动CRC编码,当余数回到最开始的值时,纠错后的CRC码也回到了最开始的位置。至此,纠错任务完成。
附录
因为上面并没有具体的计算过程,需要大家手动算,下面把我的计算过程附上。
感受
CRC的纠错过程才是其精髓所在,了解之后不由的感叹:“妙不可言,计算机前辈们都是神级大佬”。最后,祝愿大家好好学习,变得更强。
补充
至于计算机是怎么知道第一位出错时的余数,可以参见下面这篇文章,写的很好
计算机组成原理:循环冗余校验码CRC具备“一位纠错”功能的思考与探索