精华内容
下载资源
问答
  • CRC校验码C语言实现
    2022-01-05 18:27:20

    时间与空间不可得兼。。我选择空间。。空间复杂度还是很低的。。

    #include <stdio.h>
    int shi(int n){
        return (n>0)?shi(n=n>>1)+1:0;
        }
    
    void turnb(int n){
        if(n!=0){
            turnb(n>>1);
            printf("%d",n&1);
            }
    }
    int convertBinaryToDecimal(long long n)
    {
        int decimalNumber = 0, i = 0, remainder;
        while (n>0)
        {
            remainder = n%10;
            n /= 10;
            decimalNumber += remainder*(1<<i);
            ++i;
        }
        return decimalNumber;
    }
    
    int mod(int n,int k){
        int lenn=shi(n),lenk=shi(k);
        n=n<<(lenk-1);
        k=k<<(lenn-1);
        int m=0;
        int midlen;
        int reg=n;
        for(;;){
            reg=reg^k;
            midlen=shi(reg);
            if(midlen<lenk)break;
            k=k>>(shi(k)-midlen);
        }
        return reg;
    }            
            
    int main(int argc, char** argv){
        long long n,k;
        int nl,kl;
        while(1){
            printf("输入要发送的数据:");
            scanf("%lld",&n);
            printf("输入CRC生成多项式:");
            scanf("%lld",&k);
            printf("CRC校验码为:");
            nl=convertBinaryToDecimal(n);
            kl=convertBinaryToDecimal(k);
            int r=mod(nl,kl);
            turnb(r);
            printf("\n最终的发送数据为:");
            nl=nl<<(shi(kl)-1);
            nl=nl^r;
            turnb(nl);
            printf("\n\n");
        }
        return 0;
      }
    
    更多相关内容
  • 本篇文章是对使用C语言实现CRC校验的方法进行了详细的分析介绍,需要的朋友参考下
  • CRC4的C语言实现代码

    2020-08-01 18:29:24
    这里给大家分享一个函数,实现DSP通讯中的CRC4校验 。特征码为0x13。
  • CRC算法原理及C语言实现:CRC计算与普通的除法计算有所不同。普通的除法计算是借位相减的,而CRC计算则是异或运算。任何一个除法运算都需要选取一个除数,在CRC运算中我们称之为poly,而宽度W就是poly最高位的位置。...
  • CRC校验——C语言代码

    2018-03-04 13:14:12
    CRC16_CCITT、CRC16_XMODEM、CRC16_MODBUS、CRC16_MAXIM、CRC16_USB的C语言代码
  • CRC原理和C语言实现CRC

    千次阅读 2020-08-25 15:02:16
    CRC是对传输的数据进行一个差错校验的,但是不对数据进行纠错,CRC检测不通过的时候丢弃数据 CRC冗余校验 首先先明确几个点: 多项式的被除数M,也就是信息码(数据) 多项式的除数G 得到的结果冗余校验码R 以及冗余...
    〇、参考文章
    1. 最通俗的CRC校验原理剖析
    2. 循环冗余校验(CRC)算法入门引导
    3. CRC的基本原理详解
    4. CRC编码及C++实现
    5. CRC原理简介
    一、CRC原理

    CRC是对传输的数据进行一个差错校验的,但是不对数据进行纠错,CRC检测不通过的时候丢弃数据

    CRC冗余校验

    首先先明确几个点:

    • 多项式的被除数M,也就是信息码(数据)
    • 多项式的除数G
    • 得到的结果冗余校验码R
    • 以及冗余校验码的宽度W

    【注意】
    G得到的二进制长度是比W1位的,如计算CRC4,对应的宽度W4,但是生成的多项式虽然说是任意的,但是x⁴这个是必然存在的
    假设生成多项式x⁴+x³+x⁰,也就是说G对应的二进制是11001,这样,二进制对应的长度就比W1位,因为第1位必然是1,所以会把第1位忽略掉,对应的异或的值为1001,为什么忽略最高位的1,下面会解释


    下面看一下原理
    CRC算法的是以GF(2)(2元素伽罗瓦域)多项式算术为数学基础的,注意,这是一种新的运算法则
    法则规定,加减不考虑进位,所以加减是一致的,式子中不出现减号,以加号代替,因此可以用二进制的异或来运算其加法(在运算异或的时候就是加法)

    P1 = x^3  + x^2 + 1,P2 = x^3  + x^1 + 1,P1 + P2为:
    
    	x^3 + x^2     + 1									1101
    +	x^3       + x  + 1						         ^  1011
    ------------------------------      >>      ------------------------------
              x^2 + x                                       0110
    

    了解一下异或的一些性质:

    1. a ⊕ a = 0
    2. a ⊕ b = b ⊕ a    						//  异或运算满足交换律
    3. a ⊕ b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c; //  异或运算满足结合律
    4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.
    5. a ⊕ b ⊕ a = b.
    

    发送和接收的双方确定一个除数G,发送的数据对除数进行一个模2运算,将得到的余数添加到要发送的数据后面去(不是相加,是添加)
    接收方接收到数据之后对同样的余数进行模2运算,得到的余数应该是0

    假设发送的数据是10110011,双方确定的除数是11001(没有忽略最高位),确定的冗余码是4位,需要在信息码的后面添加40

    这里的模2运算就是数据后面添加冗余位数再与除数的异或运算,在最后的运算中,落下来到被除数上面的肯定是0,因为是后面添加上去的,就是图中4个附加上去的0,这就使得最后一次的运算总是被除数(11000)小于除数(11001),而他们的差异也就是余数了(0110),不够确定的冗余位数的需要补齐

    在这里插入图片描述
    得到冗余码之后,添加到数据的后面发送给接收方,接收方获得数据后,对同样的除数进行模2运算,得到的结果应该为0,为什么是0
    因为上面说了最后得出余数的那一次运算是被除数和除数之间的差异,在被除数添加上这个差异后,就不会再有余数了,故而余数为0,比如11000中,110是原来被除数落下来的,添加上0100后就是1100100,与除数(11001)做模2运算得出来的结果是0


    二、CRC检验C语言

    中间的循环代码还是比较好理解的,

    for (i = 0; i < 8; i++)             // 一个字节8位,一位一位的去异或
       {
           if (crc & 0x8000)            // 判断CRC的首位,如果是1的活,那么左移一位之后,其首位和除数被忽略的那个最高位的1异或结果位0,也可以忽略
               crc = (crc << 1) ^ POLY;	// 左移后进行异或
           else                         // 首位为0,比如异或之后结果为0,应该选首位为1的位开始继续异或,直接跳过0位
               crc <<= 1;               
       }                             
    
    	 -------------------
    11001|10110011
    	 11001		(为什么首位1在外面呢,应为代码里面的除数是没有首位的,即1001)
    	 -------------------
    	 011110110 (可以看到两者都是1,异或结果必然是0,可以直接忽略,接下来首位还是1,先移位)
    	 111101100
    	 11001
    	 -------------------
    	 001111100(忽略前面的一个0,剩下的是01111100,继续异或必然不能是下面的情况)
    	  011111000(所以首是0,跳过)(else crc<<1)
    	  1001
    

    关于下面这句话的理解,先把数据左移8位,因为下面一位一位的运算时还要移动8位,一共就是16CRC宽度,然后异或上crc,可以理解为crc时上次的余数,然后加上这次的数据,一起继续异或

    crc = crc ^ (*addr++ << 8);     	// 先是把第一个字节的数据左移8位
    
    如数据01,02连接在一起是
    0000 0001 0000 0010, 相当于0000 0001 0000 0000 + 0000 0000 0000 0010,即(01<<8)^(02)
    (01<<8)^(02)^POLY ==> (01<<8)^POLY^(02)
    (01<<8)^POLY相当于一次的外循环
    

    那么结合起来的总代码就是下面的这个

    #define POLY        0x1021
    /**
     *	@param:	addr:	存放数据的数组地址
     *			lenth:	数组长度
     *			crc:	crc初始化的值
     */
    uint16_t crc16(unsigned char *addr, int lenth, uint16_t crc)
    {
        int i;
        for (; lenth> 0; lenth--)           	// 数组有多少字节进行多少次计算
        {
            crc = crc ^ (*addr++ << 8);     	
            for (i = 0; i < 8; i++)            
            {
                if (crc & 0x8000)           
                    crc = (crc << 1) ^ POLY;   
                else                          
                    crc <<= 1;                 
            }                            
            crc &= 0xFFFF;                 // 确保出来的CRC是16位,多余的清零
        }                               
        return(crc);                   
    }
    

    2020.8.25
    展开全文
  • 32位CRC校验c语言代码

    2019-03-18 22:27:49
    32位CRC校验c语言代码,参数:内容,长度,种子值,直接调接口即可使用。
  • CRC校验的作用: 一般用于通信过程中,验证数据完整性;数据有无丢失。 校验原理&程序设计流程图 C程序验证 源码 #include <stdio.h> unsigned short RTU_CRC( unsigned char * puchMsg, unsigned ...

    CRC校验的作用:

    一般用于通信过程中,验证数据完整性;数据有无丢失。
    

    校验原理&程序设计流程图请添加图片描述

    CRC16——C程序验证

    1. 源码
    #include <stdio.h>
    unsigned short RTU_CRC( unsigned char * puchMsg, unsigned short usDataLen );
    
    int main(){
    	
    	int DateLen=11;
    	unsigned char crc[] = {0x0B,0xC1,0x08,0x21,0x92,0x64,0x10,0xD1,0x02,0x01,0x02};	
    	//check:AE B1"	 校验位,校验结果
    	
    	for (int i=0; i<DateLen; i++){
    		printf("%02X",crc[i]);
    	}
    	printf("---CRC check = %0X", RTU_CRC(crc,DateLen));
    	return 0;
    }
    // crc校验表
    static const unsigned char auchCRCHi[] = {
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80,
    0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
    0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
    0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80,
    0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40};
    // -----------------------------------------------------------------------------
    // DESCRIPTION: RTU CRC 3校验的低位字节表3
    // -----------------------------------------------------------------------------
    static const unsigned char auchCRCLo[] = {
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5,
    0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B,
    0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,
    0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
    0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2,
    0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F,
    0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB,
    0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25,
    0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C,
    0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8,
    0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D,
    0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73,
    0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57,
    0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A,
    0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E,
    0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86,
    0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
    // 3校验函数3
    /*nodebug*/ unsigned short RTU_CRC( unsigned char * puchMsg, unsigned short usDataLen )
    {
    	unsigned char uchCRCHi; // high 字节 of CRC initialized
    	unsigned char uchCRCLo; // low 字节 of CRC initialized
    	unsigned uIndex; // will index into CRC lookup table
    	uchCRCHi = 0xFF;
    	uchCRCLo = 0xFF;
    	
    	while ( usDataLen-- )
    	{
    	// calculate the CRC
    		uIndex = uchCRCLo ^ (unsigned char)( *puchMsg++ );
    		uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex];
    		uchCRCHi = auchCRCLo[uIndex];
    	} 
    	return ( uchCRCHi << 8 | uchCRCLo );
    }
    
    1. 执行结果

      0BC10821926410D1020102---CRC check = AEB1
      
    展开全文
  • CRC校验原理及其C语言实现

    千次阅读 多人点赞 2020-09-27 22:00:06
    文章目录目录前言CRC算法简介CRC参数模型CRC计算CRC校验CRC计算的C语言实现CRC计算工具总结参考资料 目录 前言 CRC算法简介 CRC计算 CRC校验 CRC计算的C语言实现 CRC计算工具 总结 前言 最近的工作中,要实现对...

    目录

    • 前言
    • CRC算法简介
    • CRC计算
    • CRC校验
    • CRC计算的C语言实现
    • CRC计算工具
    • 总结

    前言

    最近的工作中,要实现对通信数据的CRC计算,所以花了两天的时间好好研究了一下,周末有时间整理了一下笔记。

    一个完整的数据帧通常由以下部分构成:

    2020-09-20_151837

    校验位是为了保证数据在传输过程中的完整性,采用一种指定的算法对原始数据进行计算,得出的一个校验值。接收方接收到数据时,采用同样的校验算法对原始数据进行计算,如果计算结果和接收到的校验值一致,说明数据校验正确,这一帧数据可以使用,如果不一致,说明传输过程中出现了差错,这一帧数据丢弃,请求重发。

    常用的校验算法有奇偶校验、校验和、CRC,还有LRC、BCC等不常用的校验算法。

    以串口通讯中的奇校验为例,如果数据中1的个数为奇数,则奇校验位0,否则为1。

    例如原始数据为:0001 0011,数据中1的个数(或各位相加)为3,所以奇校验位为0。这种校验方法很简单,但这种校验方法有很大的误码率。假设由于传输过程中的干扰,接收端接收到的数据是0010 0011,通过奇校验运算,得到奇校验位的值为0,虽然校验通过,但是数据已经发生了错误。

    2020-09-20_125410

    校验和同理也会有类似的错误:

    2020-09-20_125438

    一个好的校验校验方法,配合数字信号编码方式,如(差分)曼彻斯特编码,(不)归零码等对数据进行编码,可大大提高通信的健壮性和稳定性。例如以太网中使用的是CRC-32校验,曼彻斯特编码方式。本篇文章介绍CRC校验的原理和实现方法。

    CRC算法简介

    循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。

    CRC校验计算速度快,检错能力强,易于用编码器等硬件电路实现。从检错的正确率与速度、成本等方面,都比奇偶校验等校验方式具有优势。因而,CRC 成为计算机信息通信领域最为普遍的校验方式。常见应用有以太网/USB通信,压缩解压,视频编码,图像存储,磁盘读写等。

    CRC参数模型

    不知道你是否遇到过这种情况,同样的CRC多项式,调用不同的CRC计算函数,得到的结果却不一样,而且和手算的结果也不一样,这就涉及到CRC的参数模型了。计算一个正确的CRC值,需要知道CRC的参数模型。

    一个完整的CRC参数模型应该包含以下信息:WIDTH,POLY,INIT,REFIN,REFOUT,XOROUT。

    • NAME:参数模型名称。

    • WIDTH:宽度,即生成的CRC数据位宽,如CRC-8,生成的CRC为8位

    • POLY:十六进制多项式,省略最高位1,如 x8 + x2 + x + 1,二进制为1 0000 0111,省略最高位1,转换为十六进制为0x07。

    • INIT:CRC初始值,和WIDTH位宽一致。

    • REFIN:true或false,在进行计算之前,原始数据是否翻转,如原始数据:0x34 = 0011 0100,如果REFIN为true,进行翻转之后为0010 1100 = 0x2c

    • REFOUT:true或false,运算完成之后,得到的CRC值是否进行翻转,如计算得到的CRC值:0x97 = 1001 0111,如果REFOUT为true,进行翻转之后为11101001 = 0xE9。

    • XOROUT:计算结果与此参数进行异或运算后得到最终的CRC值,和WIDTH位宽一致。

    通常如果只给了一个多项式,其他的没有说明则:INIT=0x00,REFIN=false,REFOUT=false,XOROUT=0x00。

    常用的21个标准CRC参数模型:

    2020-09-20_131404

    CRC校验在电子通信领域非常常用,可以说有通信存在的地方,就有CRC校验:

    • 美信(MAXIM)的芯片DS2401/DS18B20,都是使用的CRC-8/MAXIM模型
    • SD卡或MMC使用的是CRC-7/MMC模型
    • Modbus通信使用的是CRC-16/MODBUS参数模型
    • USB协议中使用的CRC-5/USB和CRC-16/USB模型
    • STM32自带的硬件CRC计算模块使用的是CRC-32模型

    至于多项式的选择,初始值和异或值的选择,输入输出是否翻转,这就涉及到一定的编码和数学知识了。感兴趣的朋友,可以了解一下每个CRC模型各个参数的来源。至于每种参数模型的检错能力、重复率,需要专业的数学计算了,不在本文讨论的范畴内。

    CRC计算

    好了,了解了CRC参数模型知识,下面手算一个CRC值,来了解CRC计算的原理。

    问:原始数据:0x34,使用CRC-8/MAXIN参数模型,求CRC值?

    答:根据CRC参数模型表,得到CRC-8/MAXIN的参数如下:

    POLY = 0x31 = 0011 0001(最高位1已经省略)
    INIT = 0x00
    XOROUT = 0x00
    REFIN = TRUE
    REFOUT = TRUE
    

    有了上面的参数,这样计算条件才算完整,下面来实际计算:

    0.原始数据 = 0x34 = 0011 0100,多项式 = 0x31 = 1 0011 0001
    1.INIT = 00,原始数据高8位和初始值进行异或运算保持不变。
    2.REFIN为TRUE,需要先对原始数据进行翻转:0011 0100 > 0010 1100
    3.原始数据左移8位,即后面补800010 1100 0000 0000
    4.把处理之后的数据和多项式进行模2除法,求得余数:
    原始数据:0010 1100 0000 0000 = 10 1100 0000 0000
    多项式:1 0011 00012除法取余数低8位:1111 1011
    5.与XOROUT进行异或,1111 1011 xor 0000 0000 = 1111 1011 
    6.因为REFOUT为TRUE,对结果进行翻转得到最终的CRC-8值:1101 1111 = 0xDF
    7.数据+CRC:0011 0100 1101 1111 = 34DF,相当于原始数据左移8+余数。
    

    模2除法求余数:

    2020-09-20_160023

    验证手算结果:

    2020-09-20_154725

    可以看出是一致的,当你手算的结果和工具计算结果不一致时,可以看看INIT,XOROUT,REFINT,REFOUT这些参数是否一致,有1个参数不对,计算出的CRC结果都不一样。

    CRC校验

    上面通过笔算的方式,讲解了CRC计算的原理,下面来介绍一下如何进行校验。

    按照上面CRC计算的结果,最终的数据帧:0011 0100 1101 1111 = 34DF,前8位0011 0100是原始数据,后8位1101 1111 是 CRC结果。

    接收端的校验有两种方式,一种是和CRC计算一样,在本地把接收到的数据和CRC分离,然后在本地对数据进行CRC运算,得到的CRC值和接收到的CRC进行比较,如果一致,说明数据接收正确,如果不一致,说明数据有错误。

    另一种方法是把整个数据帧进行CRC运算,因为是数据帧相当于把原始数据左移8位,然后加上余数,如果直接对整个数据帧进行CRC运算(除以多项式),那么余数应该为0,如果不为0说明数据出错。

    2020-09-20_161239

    而且,不同位出错,余数也不同,可以证明,余数与出错位数的对应关系只与CRC参数模型有关,而与原始数据无关。

    CRC计算的C语言实现

    无论是用C还是其他语言,实现方法网上很多,这里我找了一个基于C语言的CRC计算库,里面包含了常用的21个CRC参数模型计算函数,可以直接使用,只有crcLib.ccrcLib.h两个文件。

    • GitHub地址:https://github.com/whik/crc-lib-c
    • Gitee地址:https://gitee.com/whik/crc-lib-c
      使用方法非常简单:
    #include <stdio.h>
    #include <stdlib.h>
    #include "crcLib.h"
    
    int main()
    {
        uint8_t LENGTH = 10;
        uint8_t data[LENGTH];
        uint8_t crc;
    
        for(int i = 0; i < LENGTH; i++)
        {
            data[i] = i*5;
            printf("%02x ", data[i]);
        }
        printf("\n");
    
        crc = crc8_maxim(data, LENGTH);
    
        printf("CRC-8/MAXIM:%02x\n", crc);
        return 0;
    }
    

    计算结果:

    2020-09-20_185246

    CRC计算工具

    下面这几款工具都可以自定义CRC算法模型,而且都有标准CRC模型可供选择。如果自己用C语言或者Verilog实现校验算法时,非常适合作为标准答案进行验证。

    • 在线计算:www.ip33.com/crc.html
    • 离线计算工具:CRC_Calc v0.1.exe或者GCRC.exe

    格西CRC计算器:

    2020-09-20_153450

    总结

    CRC校验并不能100%的检查出数据的错误,非常低的概率会出现CRC校验正确但数据中有错误位的情况。这和CRC的位数,多项式的选择等等有很大的关系,所以在实际使用中尽量选择标准CRC参数模型,这些多项式参数都是经过理论计算得出的,可以提高CRC的检错能力。CRC校验可以检错,也可以纠正单一比特的错误,你知道纠错的原理吗?

    参考资料

    • https://www.cnblogs.com/liushui-sky/p/9962123.html
    • https://segmentfault.com/a/1190000018094567
    展开全文
  • 非常简易的CRC32 计算对于任意大小文件进行CRC32计算 目前采用的是POLY为0xedb88320
  • CRC校验及C语言实现

    2022-02-18 10:44:50
    摘自:CRC校验原理及其C语言实现 地址:https://blog.csdn.net/whik1194/article/details/108837493?spm=1001.2014.3001.5502
  • CRC校验的快速算法的C语言实现CC R校验的快速算法的C语言实现颜国谷 (中原油田信息中心 4 70 ) 5 0 1摘要:c c R循环冗余校验算法,是一种在数据存储和数据通讯领域中使用十分广泛的编码算法,具有强力的检错和纠错...
  • crc C语言 && 硬件实现

    2021-04-02 20:04:10
    、然后与C语言写了一个产生crc编码的代码 /* * @Author: zhifeiyu * @Date: 2021-04-02 18:22:45 * @LastEditTime: 2021-04-02 20:01:22 * @LastEditors: Please set LastEditors * @Description: In User ...
  • CRC16CRC32的C语言实现

    2021-03-03 09:46:44
    实测可用
  • C语言实现CRC编码

    千次阅读 2019-12-31 15:28:01
    CRC 的英文全称为 Cyclic Redundancy Check(Code),中文名称为循环冗余校验(码)。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。 二、CRC编码过程 ...
  • CRC校验CRC(Cyclic Redundancy Check)...用了一天时间研究了CRCC语言实现,理解和掌握了基本原理和C语言编程。结合自己的理解简单写下来。1、CRC简介CRC检验的基本思想是利用线性编码理论,在发送端根据要传送的...
  • C语言实现CRC16校校验

    2018-05-23 13:20:48
    C语言实现标准CRC16校验 ,文件包含crc.h 和crc.c,有问题可以 私聊我 q-175-543-7233
  • Modbus通信协议中CRC校验的快速C语言算法
  • CRC校验C语言实现

    2018-07-28 09:51:28
    C语言实现的,这个程序是计算CRC位。鄙人C语言小白水平,你学了C语言就能看懂。嗯,,我指针没学好,,所以我都是用数组写的,你说简单不简单。嗯,没毛病就是那种命令框框显示CRC。输入要计算CRC位的数据,然后...
  • CRC校验和C语言实现

    万次阅读 2019-06-08 18:16:08
    A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS 写给嵌入式程序员的循环冗余校验(CRC)算法入门引导 CRC (循环冗余校验) 模2运算 前言 本文首先参考了链接2的博客,上面讲的很详细,从奇偶校验、...
  • CRC校验的实现(C语言CRC16)

    千次阅读 2021-04-30 14:20:57
    一、CRC是什么? 循环冗余校验码(CRC),简称循环码,是一种常用的、具有检错、纠错能力的校验码,在早期的通信中运用广泛。循环冗余校验码常用于外存储器和计算机同步通信的数据校验。奇偶校验码和海明校验码都...
  • C语言CRC32库及demo

    2019-12-27 16:24:39
    这是CRC32的C语言版本库是及接口文档,就一个方法,传入字符串及长度,然后返回CRC32的值,干净。
  • 用表驱动法来实现CRC8、CRC16、CRC32的数据校验,程序简洁,通俗易懂
  • crc16-ccitt C语言代码

    2017-09-04 14:10:09
    crc16-ccitt 通过查表法实现,运算速度比较快,初始值为0xffff,并且是基于标准C语言的,并且已将CRC16运行程序封装成函数,只需要调用就好了,移植性强。
  • CRC校验的C语言实现

    千次阅读 2018-09-03 19:55:00
    文章转自 循环冗余校验(CRC)算法入门引导 - Ivan 的专栏 - 博客频道 - CSDN.NET http://blog.csdn.net/liyuanbhu/article/details/7882789     一、原理部分 CRC 算法的基本思想是将传输的数据当做一个...
  • CRC16校验:校验采用CRC16,多项式为X16+X12+X5+1,初始字节全部设置为0xFF,对控制代码、数据长度和数据部分做校验;
  • CRC校验以及c语言代码实现

    千次阅读 2019-11-01 16:07:01
    //CRC4 #include <stdint.h> #include <stdio.h> #define POLYNOMIAL 0xC8 /* 11011后面补0凑8位数:11011000*/ uint8_t CheckCrc4(uint8_t const message) { uint8_t remainder; //余数 uint8_t ...
  • 21个常用的CRC参数模型C语言实现

    千次阅读 2020-09-27 21:49:44
    文章目录开源地址常用的21个参数模型CRC计算工具C语言实现 开源地址 GitHub:https://github.com/whik/crc-lib-c Gitee:https://gitee.com/whik/crc-lib-c 包含常用的21个CRC参数模型实现 常用的21个参数模型 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,989
精华内容 3,595
关键字:

crc c语言