CRC校验码原理、实例、手动计算

CRC16实现代码

思路:取一个字符(8bit),逐位检查该字符,如果为1,crc^crc_mul;同时,如果原本crc最高位是1,那么crc^crc_mul后左移1位,否则只是左移一位。计算完一个字符后,装入下一个字符。

#include<stdio.h>

#define crc_mul 0x1021  //生成多项式

unsigned int cal_crc(unsigned char *ptr, unsigned char len)
{
    unsigned char i;
    unsigned int crc=0;
    while(len-- != 0)
    {
        for(i=0x80; i!=0; i>>=1)
        {
            if((crc&0x8000)!=0)
            {
               crc<<=1;
               crc^=(crc_mul);
            }else{
               crc<<=1;
            }
            if((*ptr&i)!=0)
            {
               crc ^= (crc_mul);
            }
        }
        ptr ++;
    }
    return (crc);
}

int main()
{
    unsigned char i[8] = {0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3};
    unsigned int crc;
    crc=cal_crc(i,8);
    return 0;
} 

CRC32编码字符表

#include<stdio.h>
unsigned int CRC32_table[256] = {0};
void init_CRC32_table()
{
  for (int i = 0; i != 256; i++)
  {
    unsigned int CRC = i;
    for (int j = 0; j != 8; j++)
    {
      if (CRC & 1)
        CRC = (CRC >> 1) ^ 0xEDB88320;
      else
        CRC >>= 1;
    }
    CRC32_table[i] = CRC;
  }
}
unsigned int GetCRC32(unsigned char* buf, unsigned int len)
{
  unsigned int CRC32_data = 0xFFFFFFFF;
  for (unsigned int i = 0; i != len; ++i)
  {
    unsigned int t = (CRC32_data ^ buf[i]) & 0xFF;
    CRC32_data = ((CRC32_data >> 8) & 0xFFFFFF) ^ CRC32_table[t];
  }
  return ~CRC32_data;
}

int main()
{
    unsigned char i[8] = {0x00,0x00,0x00,0x00,0x06,0x0d,0xd2,0xe3};
    init_CRC32_table();
    printf("BUFFER i‘s CRC32: 0x%x\n", GetCRC32(i,8));
    printf("CRC32 TABLE:\n");
    for(int i=0;i<256;i++)
    {
         printf("0x%8x\t",CRC32_table[i]);
         if((i+1)%8 == 0)
             printf("\n");
    }
} 

CRC校验码的手动计算示例

生成多项式:G(X)=X4+X3+1,要求出二进制序列10110011的CRC校验码。

(1)G(X)=X4+X3+1,二进制比特串为11001;(有X的几次方,对应的2的几次方的位就是1)

(2)因为校验码4位,所以10110011后面再加4个0,得到101100110000,用“模2除法”(其实就是亦或^)即可得出结果;

图5-10 CRC校验码计算示例

(3)CRC^101100110000得到101100110100。发送到接收端;

(4)接收端收到101100110100后除以11001(以“模2除法”方式去除),余数为0则无差错;

CRC校验原理

在k位信息码后再拼接r位的校验码,报文编码长度为n位,因此,这种编码又叫(n,k)码。

定理:对于一个给定的(nk)码,可以证明,存在一个最高次幂为n=k+r的多项式G(x)存在且仅存在一个R次多项式G(x),使得

其中:

m(x) :k次信息多项式,

r(x) :r-1次校验多项式,

g(x):生成多项式:

发送方通过指定的G(x)产生r位的CRC校验码,接收方则通过该G(x)来验证收到的报文码的CRC校验码是否为0。

假设发送信息用信息多项式C(X)表示,将C(x)左移r位,则可表示成C(x)*2r,这样C(x)的右边就会空出r位校验码的位置,做除法(模2除),得到的余数R就是校验码。发送的CRC编码是,验证接收到的报文编码是否至正确,依然是做模2除:。

CRC的生成多项式

生成多项式的选取应满足以下条件:

a、生成多项式的最高位和最低位必须为1。

b、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做模2除后,应该使余数不为0。

c、不同位发生错误时,应该使余数不同。

d、对余数继续做模2除,应使余数循环。

主要的生成多项式G(x)有以下几种:


名称


生成多项式


数值式


简记式


标准引用


CRC-16


x16+x15+x2+1


0x1’8005


8005


IBM SDLC


CRC-CCITT


x16+x12+x5+1


0X1’1021


0x1021


ISO HDLC,ITU X.25,V.34/V.41/V.42,PPP-FCS


CRC-32


注*


0X1’04C11DB7


0x04C11DB7


ZIP,RAR,IEEE 802 LAN/FDDI,IEEE1394,PPP-FCS

注*  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

下表中的生成多项式G(x)也常见的:


名称


生成多项式


数值式


简记式


标准引用


CRC-4


x4+x+1


0x1’3


0x3


ITU G.704


CRC-8


x8+x5+x4+1


0x1’31


0x31


CRC-8


x8+x2+x1+1


0x1’07


0x07


CRC-8


x8+x6+x4+x3+x2+x1


0x1’5E


0x5E


CRC-12


x12+x11+x3+x2+x+1


0x1’80F


0x80F


CRC-32c


注**


0X1’1EDC6F41


0x1EDC6F41


SCTP

注** x32+x28+x27+x26+x25+x23+x22+x20+x19+x18+x14+x13+x11+x10+x9+x8+x6+1

时间: 2024-08-02 15:13:38

CRC校验码原理、实例、手动计算的相关文章

Redis源码中的CRC校验码(crc16、crc64)原理浅析

在阅读Redis源码的时候,看到了两个文件:crc16.c.crc64.c.下面我抛砖引玉,简析一下原理. CRC即循环冗余校验码,是信息系统中一种常见的检错码.大学课程中的"计算机网络"."计算机组成"等课程中都有提及.我们可能都了解它的数学原理,在试卷上手工计算一个CRC校验码,并不是难事.但是计算机不是人,现实世界中的数学原理需要转化为计算机算法才能实现目的.实际上作为计算机专业背景人并不会经常使用或接触到CRC的计算机算法实现的原理,通常是电子学科背景的人士

CRC校验码的verilog实现与仿真结果

循环冗余校验码(CRC)的基本原理是: 将被处理的报文比特序列当做一个二进制多项式A(x)的系数,(任意一个由二进制位串组成的代码都可以和一个系数仅为'0'和'1'取值的多项式一一对应.例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111),该系数乘以2^n(n为生成多项式g(x)中x的最高次幂)以后再除以发送方和接收方事先约定好的生成多项式g(x)后,求得的余数P(x)就是CRC校验码,把它副到原始的报文A(x)后面形成新的报

CRC校验码

下内容摘自笔者即将出版的最新著作<深入理解计算机网络>一书.本书将于12月底出版上市,敬请留意!! 本书原始目录参见此文:http://winda.blog.51cto.com/55153/1063878 5.3.2 循环冗余校验检错方案 上节介绍的奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误. 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本

计算机网络——CRC校验码的简单测试

目录 循环冗余校验码 简单例子 程序代码 运行结果 循环冗余校验码 了解CRC校验 简单例子 实际的CRC校验码生成是采用二进制的模2算法(即减法不借位.加法不进位)计算出来的,这是一种异或操作.下面通过一些例子来进一步解释CRC的基本工作原理.假设: (1)设约定的生成多项式为G(x)=x4+x+1,其二进制表示为10011,共5位,其中k=4. (2)假设要发送数据序列的二进制为101011(即f(x)),共6位. (3)在要发送的数据后面加4个0(生成f(x)*xk),二进制表示为1010

Modbus协议 CRC 校验码

CRC(循环冗余校验)在线计算 http://www.ip33.com/crc.html 里面的8005的多项式值,但网上看到的算法都是用A001来异或的 ----------------------------------------------------- 0x8005=1000 0000 0000 0101B  0xA001=1010 0000 0000 0001B 对比两个二进制高低位正好是完全相反的,CRC校验分为正向校验与反向校验.正向校验高位在左,反向校验低位在左 正向校验使用左

[C语言]模拟人工计算CRC校验码

组成原理课程设计要实现CRC码的生成与校验,然而并不会用硬件实现... 只好先用C写着玩玩,做题还能用上...网原要考的... 例题:要发送的数据为1101011011,CRC生成多项式P(X)=X4+X+1,求应添加在数据后面的余数. 笔算过程: 编程算: 附上小白的代码... 1 #include "stdafx.h" 2 #define DATABIT_LENGTH 10 //数据位数 3 #define GENERATOR_LENGTH 5 //生成多项式位数 4 #defin

[技术栈]CRC校验原理及C#代码实现CRC16、CRC32计算FCS校验码

1.CRC.FCS是什么 CRC,全称Cyclic Redundancy Check,中文名称为循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误.它是利用除法及余数的原理来作错误侦测的. FCS,全称Frame Check Sequence,中文名称为帧校验序列,俗称帧尾,即计算机网络数据链路层的协议数据单元(帧)的尾部字段,是一段4个字节的循环冗余校验码. 注:CRC循环冗余校验和FCS帧校验序列是

CRC校验程序1:CRC循环冗余校验码计算

CRC全称Cyclic Redundancy Check,中文称为循环冗余检查.它是一种数据传输检错的机制,能够对数据进行多项式计算,并将得到的结果与接收设备共享,保证数据传输的正确性和完整性. 算法流程如下: 1. Load a 16-bit register with FFFF hex (all ‘1’s). Call this the CRC register. 2. Exclusive OR the first 8-bit byte of the message with the low

最通俗的CRC校验原理剖析

http://winda.blog.51cto.com/55153/1063951 循环冗余校验码(CRC)的检错能力更强,可以检出多位错误. 1. CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端.当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数