CRC算法原理

经过两天的学习,理解了CRC的原理及实现方法,记录于此备日后使用。(本文所有的运算,位数等讨论均是基于二进制的)CRC是Cyclic Redundancy Check的缩写,其中文翻译是循环冗余校验,该算法在通信及数字存储领域被广泛使用。以下引用维基百科中对CRC的定义:CRC为校验和的一种,是两个字节数据流采用二进制除法(没有进位,使用异或来代替减法)相除所得到的余数。其中被除数是需要计算校验和
摘要由CSDN通过智能技术生成


经过两天的学习,理解了CRC的原理及实现方法,记录于此备日后使用。(本文所有的运算,位数等讨论均是基于二进制的)

CRC是 Cyclic Redundancy Check的缩写,其中文翻译是循环冗余校验,该算法在通信及数字存储领域被广泛使用。以下引用维基百科中对CRC的定义: CRC为校验和的一种,是两个字节数据流采用二进制除法(没有进位,使用异或来代替减法)相除所得到的余数。其中被除数是需要计算校验和的信息数据流的二进制表示;除数是一个长度为n + 1的预定义(短)的二进制数,通常用多项式的系数来表示。在做除法之前,要在信息数据之后先加上n个0.

用通俗的话讲CRC的校验过程就是将待校验的数据也就是我们需要存储或者发送的信息看做一个有限长的二进制数A,然后选择一个除数B,通过定义的一种CRC除法运算求得A/B的余数,这个余数也就是我们需要求的CRC校验和。在进一步了解CRC算法之前我们需要知道三个CRC的基本概念。
1.CRC的位宽
根据余数的二进制位数不同我们又将CRC算法用CRC-N来表示,N就表示算法的余数位数,这个位数就是CRC算法的位宽。目前被广泛应用余数位数N有16和32两种。
2.除数的选择
CRC位宽确定之后,我们就需要确定除数了。由原来已有的数学知识我们就已经知道余数和除数存在一定的关系——余数要小于除数。CRC算法的求余数过程不是我们认识的严格意义的除法运算,我们对除数和余数的关系进行如下定义:假设余数位数为N,则除数位宽应该为N+1。为什么需要这样的定义,我们可以从后文的CRC除法运算过程找到答案。(位宽的计算方式为:假设二进制序列最低位位置序号记为1,高位位置序号递增,则最高不为0位的位置序号称为该二进制序列的位宽。)
3.补零操作
CRC计算过程中为了让每一个原始信息都能够参与余数计算我们需要对原来的信息添加N个0到信息末尾。这个操作我们称之为补零操作。
4.CRC除法运算
CRC除法运算实际上就是不计进位的模2除法计算过程,逻辑上表现为位和位之间的异或运算。

下边用一个简单的例子直观的例子给出CRC的计算过程,为了方便直观我们进行一次CRC-4的求取过程,同时取原始信息为10位的二进制序列1101011011。按照之前的约定我们首先需要根据余数位宽来确定除数,余数位宽为4位,则除数必须为5位,现选用10011来作为除数,然后我们需要对原始信息进行补零操作,补零后的信息为
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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校验码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值