目录
- 1. 简介
- 2. 原理
- 2.1 CRC的发送与接收
- 2.2 CRC校验码的生成
- 2.3 CRC校验码的校验
- 3. 拓展问题
- 3.1 模2除法为什么等同于异或运算?
- 3.2 为什么除数的位数和被除数补充的位数相差为1?
- 3.3 为什么CRC校验码不能纠正错误,只能检测错误?
- 4. 总结
1. 简介
在数字信号的通信中,常常会因各种因素导致传输错误,于是,聪明的科学家以及开发人员便设计,研发出了各种防止传输错误的方法。校验码便是最常见的一种。👍
最常见的校验码是奇偶校验码,仅仅只占一位,便可以根据数据中0
或者1
的数量对数据提供校验;然而奇偶校验的缺点也很明显,首先,它对错误的检测概率大约只有50%
。也就是只有一半的错误它能够检测出来。另外,每传输一个字节都要附加一位校验位,对传输效率的影响很大(奇偶校验很简单,感兴趣的可以自己了解一下,不再赘述)。
奇偶校验优点也很明显,它很简单,因此可以用硬件来实现,这样可以减少软件的负担。
CRC(Cyclic Redundancy Check)循环冗余检验,是一种用于检测数据传输中出现错误的校验方法。其特征是信息字段和校验字段的长度可以任意选定。它通过生成一个循环冗余校验码,将校验码附加到待传输的数据中,接收方再根据相同的算法对收到的数据进行校验,如果校验码无误,则可以判定数据传输正确。
CRC校验可以有效地检测传输过程中可能发生的位错误、丢失数据或假包等问题,是一种常用的数据完整性保护方法。其优点是简单、高效,并且能够在较低的计算负载下提供较高的校验能力。
需要注意的是,CRC校验不能纠正错误,只能检测错误。在数据传输的场景中,如果发现数据传输存在错误,通常需要重新发送或采取其他的错误处理措施。
2. 原理
CRC能被广泛采用,肯定有其“过人之处”,让我们来看看它的庐山真面目。
2.1 CRC的发送与接收
发送方 给出需要传递的数据(Data),并定义多项式,以多项式得到(n+1)位除数(divisor),对数据的末尾补上n
位0
,作为被除数,用除数去除被除数,得到的余数就是所需要计算的n位CRC校验码,将得到的CRC校验码拼接到原始数据的末端生成新的数据,将这个数据一并传给接收方。
接收方 将得到的一整块数据作为被除数,用在发送方得到的除数去除被除数,如果结果余数为0
的话,代表数据的传输没有出错,得到的数据是正确且有效的。反之当前数据有误,将当前数据丢弃,并通知发送方重新发送。
还有另一种方法:发送方分别发送数据和CRC数据,结束方得到数据末尾补n
个0
作为被除数,用多项式除数去除被除数,得到的余数如果作为接收方的CRC校验码,如果接收方得到的CRC数据和发送方发的CRC一致的话,同样也可以证明数据的传输是没有问题的(本文采用第一种方法)。
所谓的发送方和接收方,一般是指参与通信的两个芯片/ 模块。
2.2 CRC校验码的生成
CRC运算,也就是这种特殊的除法运算,必须要指定个除数,在CRC算法中,这个除数有一个专有名称叫做“生成多项式”。生成多项式的选取是个很有难度的问题,如果选的不好,那么检出错误的概率就会低很多。不过专家早已经考虑到了这个问题,给我们提供了好多个生成多项式可供选择。11001
便是其中之一(生成多项式的要求之一就是最高位和最低位必须为1
)。
假设我们现在需要传输一个8位二进制数据10110011
。我们选择除数为11001
,根据计算规则,在被除数后添加4
个0
。
可以看到,计算结果为100
,为了保证位数,在前面添加一个0
,变成了0100
,所以要发送的数据=原数据+CRC校验码,也就是101100110100
。
2.3 CRC校验码的校验
在接收方收到数据(其实是数据与CRC合并后的新数据)后,将其除以我们定义的除数,若结果为0
,则说明结果没错,反之当前数据有误,将当前数据丢弃,并通知发送方重新发送。计算过程如下。
从上述例子来看,余数为0
,说明数据传输没有问题。此时可对此次传输的数据做下一步处理,并准备接收新的数据。
3. 拓展问题
3.1 模2除法为什么等同于异或运算?
模2除法与算术除法类似,但每一位除的结果不影响其它位。只需要自己简单模拟一遍便可知道。
分成4中情况:
- 0-0:这个结果自然是0
- 1-1:同上,结果为0
- 0-1:向高位借1,当2用,所以结果为1
- 1-0:显然,结果为1
数据A | 0 | 0 | 1 | 1 |
---|---|---|---|---|
数据B | 1 | 0 | 1 | 0 |
异或运算的结果 | 1 | 0 | 0 | 1 |
所以,我们可以得出结论,从结果上看,模2除法与异或运算是等同的。
3.2 为什么除数的位数和被除数补充的位数相差为1?
这个问题并不难回答,这和除数,也就是生成多项式的特征有关系,在特征多项式中,最高位和最低位都为1
,而除法运算中,每次参与异或运算的两个数,最高位必然都为1
(“被减数”最高位为零则位数不够,必须向低位借数值),这样一来,运算的结果/中间结果最高位为0
,没有实际意义,所以余数最多也会比除数少1
位。
3.3 为什么CRC校验码不能纠正错误,只能检测错误?
- CRC校验码是通过需要发送的原数据计算得来的,为了保证通信效率,一般CRC校验码的长度会比原数据短(校验码是“辅助数据”)。但每一位只能表示0和1,且原数据的值分布一般没有规律,所以不可能存在这样的逆变换,使CRC校验码生成原数据。
- 即使存在这样的逆变换,又如何保证CRC校验码传输正确呢?
综上所述,CRC校验码不能纠正错误,只能检测错误。且一般情况下,用到CRC校验码的场景,通信速率都很高,所以在检出错误数据的时候,重新传输是一种简单便捷的方法。
4. 总结
CRC校验在CAN通信中用得比较多,对于确保数据传输的准确性起着非常重要的作用。
参考链接(均来自CSDN):
- 循环冗余校验(CRC)算法入门引导
- CRC校验原理及步骤
- 【科普】CRC校验(一)什么是CRC校验?