CRC笔记

       现在的CPU来说,基本上都在硬件上实现了CRC校验。

       使用查表法从软件上来实现CRC-32的校验。

       CRC还有一种反转的情况,实际上反转和不反转没有什么太大的区别,主要是需求和标准的不同。

CRC校验中的查表法是一种优化CRC计算的方法,通过预先生成一个CRC校验表(也称为查表),可以加快CRC校验的计算速度。

具体来说,CRC校验通常涉及到大量的位运算和异或操作,这些操作在传统的CRC计算方法中可能需要大量的时间来完成,尤其是对于较长的数据帧和复杂的CRC多项式。为了提高CRC计算的效率,可以采用查表法来加速计算过程。

查表法的基本思想是在CRC校验初始化阶段,预先计算生成一个CRC校验表,表中存储了不同数据字节值对应的CRC校验结果。在实际进行CRC校验时,只需要按照数据字节逐个查询表中对应的CRC校验结果,并根据预先计算好的表格进行异或操作,而不需要每次都重新计算CRC校验值。

       查表法原理

如果我们要软件上实现CRC的话,要一位一位的做这些运算,效率是非常低的,所以我们就想能不能每8位计算一次,因为每个特定的数字与这个被除数的经过8次移位操作得到的异或结果都是相同的。

(1)为什么不每16位计算一次?

这样就要保存 2^16 个uint16_t类型的数据,一个表格就有128KB,这比很多单片机的Flash要大了

(2)每8位计算一次的理论依据是什么

我们知道CRC(0)=0,然后由前面分析出的特性,我们可以推导出这个公式: CRC(A+B)=CRC(A)+CRC(B)。

现在举个例子,假如我们想求CRC(0×abcdef12),他就可以等价于:

CRC(0×abcdef12)=CRC(0×ab000000)+CRC(0×00cdef12)=CRC(0×ab)+CRC(0×cd)+CRC(0×ef)+CRC(0×12)

假如我们定义一个8位的查表表格,这样我们就可以把本来每次要进行的32次移位和异或的运算缩短为了4次。

       CRC32表格生成

经过前面的分析,我们知道,我们就是需要给uint8_t范围内(0~255)的每一个数做一下模二除法,然后将得到的结果保存到一个类型为uint8_t、大小为256的表格中。我们只需要判断CRC的最高位是否为1,若为0则将CRC左移一位,若为1则先将CRC左移1位,然后和多项式做异或运算。CRC32表格生成代码如下:

void GenerateTable(uint32_t polynomial){

       for (int byte = 0; byte < 256; ++byte){

              uint32_t crc = byte;

              for (int bit = 32; bit > 0; --bit){

                     if (crc & 0x80000000){

                              crc = (crc << 1) ^ polynomial;

                     }else{

                              crc <<= 1;

                     }

              }

              crcTable[byte] = crc;

        }

}

       CRC查表代码实现

有了前面的表格,我们使用下面的函数就能计算长度为len的字符串msg的CRC32了,在循环中,将CRC的高八位所对应的数在CRC32表格中的结果与上次计算出来的CRC右移八位的结果进行异或,最后就得到了这个字符串的CRC结果了。

unsigned int calcMsgCRC(char *msg, unsigned int len){

    unsigned long crc = 0;

    for (int n = 0; n < len; n++)    {

           uint8_t c = msg[n] & 0xff;

        crc = crcTable[(crc >> 24) ^ c] ^ (crc << 8);

    }

    return crc;

}

原文链接:https://blog.csdn.net/tilblackout/article/details/131198350

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值