CRC基本原理及实现方法

1.什么是CRC

        今天来聊一聊CRC的话题,首先第一个问题就是什么是CRC?CRC被称为循环冗余校验码,它是一种通信中常用的校验码,能让通信设备对接收到的数据进行正确与否的校验,即它能通过添加的冗余码字来判别接收的信息是否出错,但也仅仅是检验是否出错,并不能发现出错的位置以及纠正错误,因此一般会与重传机制联合使用来提高通信的可靠性。

2.CRC如何实现校验功能

        首先CRC的产生与待发送的数据是息息相关的,这种关联性也是接收端判决的依据。例如我们要传输一个长度为K比特的数据,会先通过这K比特的数据与特定多项式(也称生成多项式)来得到一组长度为R比特的校验码字,然后将这K+R比特的数据前后组合在一起发送出去。接收端接收数据后就可以利用这K+R比特的数据来判断这组数据是否出错了。接收设备将接收的K+R比特组合数据中的前K比特拿出来,并进行与发送端一模一样操作,它就会得到另一组长度R比特校验数据,这时候如果自己计算的校验数据与接收到的校验数据完全一致,则说明接收的数据是正确的,如果两者不一致,就说明传输的过程中出现了错误,至于这错误是原始的K比特出错了还是添加的R比特校验位出错了,不重要。重要的是需要重传。

3.CRC产生校验码的过程

        在说明CRC码字如何产生前,先说明下二进制系数多项式与二进制数列的对应关系,例如多项式x4+x2+x+1 对应的二进制序列为10111,这个二进制序列就是多项式的系数数列,其中0代表没有这个次幂的数据。这里的多项式都是属于GF(2),也就是其系数都是二进制的数,而且其多项式的各项运算,如加减乘除,都需进行模2的运算,比如x2+x2=0,因为mod[(1+1),2]x2=0*x2=0。
        设待编码的二进制数据序列长度为N,且其对应的二进制系数多项式为P(x), 产生CRC码字的生成多项式为G(x),生成的CRC码字长度为K,且其对应的二进制系数多项式为R(x),则待编码二进制序列与生成的CRC码字序列组合成的新二进制序列对应的二进制系数多项式为Y(x)=xN-KP(x)+R(x),以上信息明确后,根据生成多项式G(x)产生的CRC码字需满足: 多项式Y(x)除以G(x)的余数为0。找到满足条件的R(x)后,其对应的二进制序列就是该生成多项式下的CRC编码结果。
        下面来看怎么找满足条件的R(x)。首先通过上述的说明可以看到xN-KP(x)是不能被G(x)整除的,因此设xN-KP(x)除以G(x)的商为Q(x),余数为 R*(x),则
                        xN-KP(x)=Q(x)G(x) + R*(x)
        在上式两边都加上R*(x),则能得到
                        xN-KP(x)+R*(x)=Q(x)G(x)     注:这里的加法是系数的模2加
        可见xN-KP(x)+R*(x)能够被G(x)整除,那么R*(x)就是我们要找的那个R(x),也就是说我们要找的CRC码字。
        在实际的编码中,我们一般不直接使用多项式除法来求多项式R(x),而是使用二进制除法直接求出R(x)对应的二进制序列。也就是说求CRC码字的最终过程就是将多项式xN-KP(x)对应的二进制序列,除以多项式G(x)对应的二进制序列,这个除法运算的余数就是我们要求的CRC码字

3.1多项式除法对应的二进制序列除法

        下面以具体的实例来说明如何用二进制的除法形式来实现多项式除法。首先说明一下二进制的除法形式实现的多项式除法应该遵循的基本规则(由GF(2)的计算规则得出),即在二进制除法形式的计算中,都是模2运算,而除法中涉及的就是减法和乘法,其中乘法就是直接乘,而减法就相当于异或运算,且不存在进位和借位操作(因为不同位置的二进制数代表了多项式的不同次幂系数,而计算过程只能同次幂的系数进行四则运算),举例如下:
       被除数多项式P(x)=x7+x6+x5+x4+x, 除数多项式G(x)= x3+x2+1,则这两个多项式对应的二进制数据分别为P=11110010, G=1101,其除法计算过程见下图
在这里插入图片描述
上式中带加号的圆圈表示异或,蓝色为商,红色为每次计算的余数,商为10111,也就是x4+ x2+x+1,余数为1。被除数前面添加的三个红色0为余数的初始值。下面使用“被除数=除数x商+余数 ”来验证下上式的计算是否正确。
在这里插入图片描述
验证的过程使用了多项式的乘法,而这个也要遵循GF(2)的计算规则,即相同幂次的系数是异或运算进行合并(也是模2加运算),通过验证可以看到这样的二进制除法形式的运算是可以等效于多项式除法的。但这样的运算形式并不适合用来编写程序实现,所以下一步骤来说明如何在代码中实现多项式除法。

3.2 多项式除法的LFSR实现

        多项式除法是可以通过LFSR来实现的,在说明实现方法之前,需要从上面的二进制除法竖式中寻找到一点规律,那就是每一步得到的商的值(蓝色)都等于前一步余数(红色)的最左侧值(高位)
        因为计算的结果是得到余数,因此设LFSR的长度为余数的长度,并得到如下图一样的LFSR
在这里插入图片描述

  1. 上图方框代表寄存器,里面存放的是余数,其初始值全为0,其长度为生成多项式G(x)的最高次幂-1。
  2. 输入bin是P(x)多项式对应的二进制数列,由高位至低位依次输入。
  3. LFSR的反馈线系数由除数,即多项式G(x)的二进制序列构成,其中高位在右侧。上图反馈线的开关的通断由G(x)的二进制序列gx的值决定,当为1是接通,当为0时是断开,由于CRC的生成多项式G(x)的最高位和最低位必须为1,所以这里g0和gr的反馈线是直接接通的。
  4. bf是这个LFSR实现的除法器的商,其值与br-1相同,即与余数的最高位相同。
  5. bout是输出的商,在CRC编码里可以忽略这个输出。
  6. 当p(x)对应的二进制序列输入完毕后,reg内剩下的数据就是最终的余数值,且高位在右侧。

上图描述的是P(x)除以G(x)的计算过程,但在CRC编码中我们实际要计算的是xN-KP(x)除以G(x)的余数,这个xN-K怎么实现呢,其实在LFSR中xN-K就是一个数据整体向高位位移的过程,因此将上面的LFSR修改为下图形式,就能实现xN-KP(x)除以G(x)的过程
在这里插入图片描述         上面的LFSR就是实现xN-KP(x)除以G(x)的结构,当p(x)由高位至低位输入完毕后,寄存器内的数据就是CRC的编码结果。
        对于上图的LFSR再说一点,就是这个商的值bf为什么会是p(x)的当前输入与余数最高位的异或运算,可以自己通过前面讲的除法竖式来寻找这个规律。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CRC算法原理是一种简单的循环冗余校验(Cyclic Redundancy Check)算法,主要用于数据传输过程中的差错检测。 其基本思想是将要发送的数据看作二进制位序列,通过生成多项式进行计算,得到一个余数。将该余数附加到要发送的数据后面,接收方在接收到数据后也进行一系列的计算与检验,如果得到的余数为0,则认定数据无误。 具体的实现步骤是: 1. 定义生成多项式,通常用多项式的系数表示,例如CRC32使用的是0x04C11DB7。生成多项式选择不同,CRC算法的效果也会不同。 2. 将要发送的数据按照二进制形式进行排列,并进行位填充(通常在数据后面加上若干个0)。 3. 选择一个初始的除数,通常为全1或全0。 4. 将数据与初始的除数进行异或运算,得到余数。 5. 将余数附加到原始数据后面,并作为新的输入数据进行下一轮的计算,重复前面的步骤。 6. 最终得到的余数即为CRC校验,将其附加到要发送的数据后面。 7. 接收方收到数据后按照相同的生成多项式和步骤进行计算,如果最终的余数为0,则认定数据无误。 在C语言中,可以通过使用位运算和循环来实现CRC算法。具体的实现如下: ```c #include <stdio.h> unsigned int crc32(unsigned char *data, unsigned int length) { unsigned int crc = 0xFFFFFFFF; unsigned int i, j; for (i = 0; i < length; i++) { crc ^= data[i]; for (j = 0; j < 8; j++) { if (crc & 1) crc = (crc >> 1) ^ 0xEDB88320; else crc >>= 1; } } return crc ^ 0xFFFFFFFF; } int main() { unsigned char data[] = "123456789"; unsigned int length = sizeof(data) - 1; unsigned int crc = crc32(data, length); printf("CRC32: %08X\n", crc); return 0; } ``` 以上代实现了一个简单的CRC32算法,能够计算出输入数据的CRC校验。具体的计算过程是将输入数据转化为二进制形式,并进行异或和位移运算,最后输出CRC校验

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值