问一下计算机大神。crc16与crc32有啥区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了问一下计算机大神。crc16与crc32有啥区别相关的知识,希望对你有一定的参考价值。

一、生成多项式不同:

1、crc16的生成多项式为:X16+X15+X2+1。

2、crc32的生成多项式为:X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1

二、表示法不同:

1、crc16的的表示法为:0X18005,其对应校验二进制位列为1 1000 0000 0000 0101。

2、crc32的表示法为:0x104C11DB7,CRC32的生成项是: 1 0000 0100 1100 0001 0001 1101 1011 0111  (33个比特) ,颠倒过来,就可以写成1110 1101 1011 1000 1000 0011 0010 0000 1 一般生成项简写时不写最高位的1,故生成项是0x04C11DB7,颠倒后的生成项是0xEDB88320 

CRC32的生成项是33比特,最高位是消掉的,即CRC值是32比特(4个字节),即宽度W=32,就是说,在计算前,原始数据后面要先扩展W=32个比特0,即4个0x00字节。

三、应用不同:

1、crc16应用在 按位计算:程序空间十分苛刻但 CRC 计算速度要求不高的微控制器系统按字节计算:程序空间较大且 CRC 计算速度要求较高的计算机或微控制器系统,半字节计算:程序空间不太大,且 CRC 计算速度又不可以太慢的微控制器系统。

2、crc32应用在 ZIP, RAR,IEEE 802 LAN/FDDI,IEEE 1394,PPP-FCS。

参考资料来源:百度百科-CRC32

参考资料来源:百度百科-CRC

参考技术A 循环冗余码的校验长度不一样。
一般是冗余码越长,数据要求的安全性越高。
根据所要保证数据完整性的数据长短进行选择。

CRC校验具还有自动纠错能力。CRC-12码通常用来传送6-bit字符串;CRC-16及CRC-CCITT码则用是来传送8-bit字符;CRC-32码用于硬盘数据,网络传输等。CRC校验在WinRAR、以太网卡芯片、MPEG解码芯片中有着广泛的应用。

一般情况下,R位生成多项式产生的CRC码可检测出所有的双错、奇数位错和突发长度小于
等于R的突发错以及(1-2-(R-1))的突发长度为R+1的突发错和(1-2-R)的突发长度大于R+1的突发错。例如,对上述R=16的情况,就能检测出100%的突发长度小于等于16的突发错以及99.997%的突发长度为17的突发错和99.998%的突发长度大于17的突发错。这里,突发错误是指几乎是连续发生的一串错,突发长度就是指从出错的第一位到出错的最后一位的长度(中间并不一定每一位都错)。(“16位循环冗余校验码CRC的原理和性能分析”)
CRC校验码计算不同的应用系统,拥有的硬件资源不一样,要求的数据传输速度也不一样。因此可将应用系统分为3类:一是程序存储空间有限,但对CRC计算速度要求不高的微控制系统;二是程序存储空间较大且对CRC计算速度要求较高的计算机或微控制系统;三是程序存储空间不太大,且对CRC计算速度又有一定要求的微控制系统。根据不同的应用系统采取相应的CRC算法,
CRC校验码的生成有按位计算、按字节计算和按半字节计算等方法,本回答被提问者采纳

CRC32的计算方法

各位高手,问一下怎么在C++中实现CRC32的计算
先谢谢了.

CRC的本质是模-2除法的余数,采用的除数不同,CRC的类型也就不一样。通常,CRC的除数用生成多项式来表示。 最常用的CRC码及生成多项式名称生成多项式。

CRC-12:

CRC-16:

CRC-CCITT:

CRC-32:

CRC校验实用程序库 在数据存储和数据通讯领域,为了保证数据的正确,就不得不采用检错的手段。在诸多检错手段中,CRC是最著名的一种。CRC的全称是循环冗余校验。


扩展资料

通常的CRC算法在计算一个数据段的CRC值时,其CRC值是由求解每个数值的CRC值的和对CRC寄存器的值反复更新而得到的。这样,求解CRC的速度较慢。通过对CRC算法的研究,我们发现:一个8位数据加到16位累加器中去,只有累加器的高8位或低8位与数据相作用,其结果仅有256种可能的组合值。

因而,我们可以用查表法来代替反复的运算,这也同样适用于CRC32的计算。本文所提供的程序库中,函数crchware是一般的16位CRC的算法。mk-crctbl用以在内存中建立一个CRC数值表。

参考资料来源:百度百科-CRC32

参考技术A

  CRC 算法是以 GF(2) 多项式算术为数学基础的,GF(2) 多项式中只有一个变量 x ,其系数也只有 0 和 1 ,比如:

  1 *x^6 + 0*x^5 + 1*x^4 + 0*x^3 + 0*x^2 +1*x^1 + 1*x^0

  = x^6 + x^4 + x + 1

  加减运算不考虑进位和退位。说白了就是下面的运算规则:

  0 + 0 = 0    0 - 0 = 0

  0 + 1 = 1    0 - 1 = 1

  1 + 0 = 1    1 - 0 = 1

  1 + 1 = 0    1 - 1 = 0

  看看这个规则,其实就是一个异或运算。

  每个生成多项式的系数只能是 0 或 1 ,因此我们可以把它转化为二进制形式表示, 比如 g(x)=x^4 + x + 1 ,那么g(x) 对应的二进制形式就是 10011 , 于是我们就把 GF(2) 多项式的除法转换成了二进制形式,和普通除法没有区别,只是加减运算没有进位和退位。

  比如基于上述规则计算 11010/1001 ,那么商是 11 ,余数就是 101 ,简单吧。

  

  CRC 校验的基本过程

  采用 CRC 校验时,发送方和接收方用同一个生成多项式 g(x) , g(x) 是一个 GF(2) 多项式,并且 g(x) 的首位和最后一位的系数必须为 1 。

  CRC 的处理方法是:发送方用发送数据的二进制多项式 t(x) 除以 g(x) ,得到余数 y(x) 作为 CRC 校验码。校验时,以计算的校正结果是否为 0 为据,判断数据帧是否出错。设生成多项式是 r 阶的(最高位是 x^r )具体步骤如下面的描述。

  发送方:

  1 )在发送的 m 位数据的二进制多项式 t(x) 后添加 r 个 0 ,扩张到 m+ r 位,以容纳 r 位的校验码,追加 0 后的二进制多项式为  T(x) ;

  2 )用 T(x) 除以生成多项式 g(x) ,得到 r 位的余数 y(x) ,它就是 CRC 校验码;

  3 )把 y(x) 追加到 t(x) 后面,此时的数据 s(x) 就是包含了 CRC 校验码的待发送字符串;由于 s(x) = t(x) y(x) ,因此 s(x) 肯定能被 g(x) 除尽。

  接收方:

  1 )接收数据 n(x) ,这个 n(x) 就是包含了 CRC 校验码的 m+r 位数据;

  2 )计算 n(x) 除以 g(x) ,如果余数为 0 则表示传输过程没有错误,否则表示有错误。从 n(x) 去掉尾部的 r 位数据,得到的就是原始数据。

  生成多项式可不是随意选择的,数学上的东西就免了,以下是一些标准的 CRC 算法的生成多项式:

  

  原始的 CRC 校验算法

  根据多项式除法,我们就可以得到原始的 CRC 校验算法。假设生成多项式 g(x) 是 r 阶的,原始数据存放在 data中,长度为 len 个 bit , reg 是 r+1 位的变量。 以 CRC-4 为例,生成多项式 g(x)=x^4 + x + 1 ,对应了一个 5bits 的二进制数字 10011 ,那么 reg 就是 5 bits 。

  reg[1] 表明 reg 的最低位, reg[r+1] 是 reg 的最高位。

  通过反复的移位和进行除法,那么最终该寄存器中的值去掉最高一位就是我们所要求的余数。所以可以将上述步骤用下面的流程描述:

  改进一小步——从 r+1 到 r

  由于最后只需要 r 位的余数,所以我们可以尝试构造一个 r 位的 reg ,初值为 0 ,数据 data 依次移入 reg[1] ,同时把reg[r] 移出  reg 。

  根据上面的算法可以知道,只有当移出的数据为 1 时, reg 才和 g(x) 进行 XOR 运算;于是可以使用下面的算法:

  

参考技术B 资料中拷贝下来的,希望对你有帮助

为了提高编码效率,在实际运用中大多采用查表法来完成CRC-32校验,下面是产生CRC-32校验吗的子程序。
unsigned long crc_32_tab[256]=
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,0x0edb8832,…, 0x5a05df1b, 0x2d02ef8d
;//事先计算出的参数表,共有256项,未全部列出。

unsigned long GenerateCRC32(char xdata * DataBuf,unsigned long len)

unsigned long oldcrc32;
unsigned long crc32;
unsigned long oldcrc;
unsigned int charcnt;
char c,t;
oldcrc32 = 0x00000000; //初值为0
charcnt=0;
while (len--)
t= (oldcrc32 >> 24) & 0xFF; //要移出的字节的值
oldcrc=crc_32_tab[t]; //根据移出的字节的值查表
c=DataBuf[charcnt]; //新移进来的字节值
oldcrc32= (oldcrc32 << 8) | c; //将新移进来的字节值添在寄存器末字节中
oldcrc32=oldcrc32^oldcrc; //将寄存器与查出的值进行xor运算
charcnt++;

crc32=oldcrc32;
return crc32;

参数表可以先在PC机上算出来,也可在程序初始化时完成。下面是用于计算参数表的c语言子程序,在Visual C++ 6.0下编译通过。
#include <stdio.h>
unsigned long int crc32_table[256];
unsigned long int ulPolynomial = 0x04c11db7;
unsigned long int Reflect(unsigned long int ref, char ch)
unsigned long int value(0);
// 交换bit0和bit7,bit1和bit6,类推
for(int i = 1; i < (ch + 1); i++)
if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1;
return value;

init_crc32_table()
unsigned long int crc,temp;
// 256个值
for(int i = 0; i <= 0xFF; i++)
temp=Reflect(i, 8);
crc32_table[i]= temp<< 24;
for (int j = 0; j < 8; j++)
unsigned long int t1,t2;
unsigned long int flag=crc32_table[i]&0x80000000;
t1=(crc32_table[i] << 1);
if(flag==0)
t2=0;
else
t2=ulPolynomial;
crc32_table[i] =t1^t2 ;
crc=crc32_table[i];
crc32_table[i] = Reflect(crc32_table[i], 32);

参考资料:http://www0.ccidnet.com/tech/msrc/2001/03/14/58_1827.html

本回答被提问者采纳
参考技术C 一篇通俗易懂的关于CRC的文章
https://zhuanlan.zhihu.com/p/81294341

以上是关于问一下计算机大神。crc16与crc32有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

CRC32的计算方法

计算CRC校验值(CRC16和CRC32)(网络传输检验)

求助大神还都有哪些16位冗余校验计算方法,试过常见的几种CRC16都不对

STM32 HAL_CRC 16 位

STM32 CRC寄存器

STM32 CRC寄存器