精华内容
下载资源
问答
  • CRC校验码计算过程
    千次阅读
    2021-05-19 17:13:10

    namespace CRC
    {
        class Program
        {
            static void Main(string[] args)
            {
                byte[] date = { 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00 };   //要计算CRC校验的数据
                byte[] crc = new byte[2];    //用来保存CRC效验码
                crc = GetCRC(date);         //得到data的CRC码
                foreach (var item in crc)   
                {
                    Console.Write(item.ToString("X2") + "  ");    //打印出CRC码
                }
                Console.WriteLine();
                Console.ReadKey();
            }


            public static byte[] GetCRC(byte[] byteData)   //计算CRC校验的数据方法
            {
                byte[] CRC = new byte[2];

                UInt16 wCrc = 0xFFFF;
                for (int i = 0; i < byteData.Length; i++)
                {
                    wCrc ^= Convert.ToUInt16(byteData[i]);
                    for (int j = 0; j < 8; j++)
                    {
                        if ((wCrc & 0x0001) == 1)
                        {
                            wCrc >>= 1;
                            wCrc ^= 0xA001;    //异或多项式
                        }
                        else
                        {
                            wCrc >>= 1;
                        }
                    }
                }

                CRC[1] = (byte)((wCrc & 0xFF00) >> 8);    //高位在后
                CRC[0] = (byte)(wCrc & 0x00FF);               //低位在前
                return CRC;

            }
        }
    }

    更多相关内容
  • 1.CRC-16/MODBUS(最通用) 2.CRC-16/CCITT-FALSE 支持以上CRC校验计算方式(分查表法和计算法),原代码可执行,能正确输出结果。需要的朋友可以直接 引用到自己项目中。谢谢支持。
  • 循环冗余校验码(CRC)计算代码合集,里面包含了各种编程语言(包括C,C++,单片机等)CRC代码的实现
  • 详述CRC校验码(附代码

    千次阅读 2021-08-26 00:15:28
    关注+星标公众号,不错过精彩内容来源| 一口LinuxCRC校验应用比较广泛,通常在通信领域用的比较多,即便是自定义通信协议,也可以添加CRC校验码,使其通信更加可靠。今天就来进一步描述...

    关注+星标公众,不错过精彩内容

    来源 | 一口Linux

    CRC校验应用比较广泛,通常在通信领域用的比较多,即便是自定义通信协议,也可以添加CRC校验码,使其通信更加可靠。

    今天就来进一步描述CRC校验码。

    一、CRC概念

    1. 什么是CRC?

    CRC(Cyclic Redundancy Checksum)是一种纠错技术,代表循环冗余校验和。

    数据通信领域中最常用的一种差错校验码,其信息字段和校验字段长度可以任意指定,但要求通信双方定义的CRC标准一致。主要用来检测或校验数据传输或者保存后可能出现的错误。它的使用方式可以说明如下图所示:

    在数据传输过程中,无论传输系统的设计再怎么完美,差错总会存在,这种差错可能会导致在链路上传输的一个或者多个帧被破坏(出现比特差错,0变为1,或者1变为0),从而接受方接收到错误的数据。

    为尽量提高接受方收到数据的正确率,在接收方接收数据之前需要对数据进行差错检测,当且仅当检测的结果为正确时接收方才真正收下数据。检测的方式有多种,常见的有奇偶校验因特网校验循环冗余校验等。

    2. 使用方法概述

    循环冗余校验是一种用于校验通信链路上数字传输准确性的计算方法(通过某种数学运算来建立数据位和校验位的约定关系的 )。

    发送方计算机使用某公式计算出被传送数据所含信息的一个值,并将此值 附在被传送数据后,接收方计算机则对同一数据进行 相同的计算,应该得到相同的结果。

    如果这两个 CRC结果不一致,则说明发送中出现了差错,接收方计算机可要求发送方计算机重新发送该数据。

    3. 应用广泛

    在诸多检错手段中,CRC是最著名的一种。CRC的全称是循环冗余校验,其特点是:检错能力强,开销小,易于用编码器及检测电路实现。从其检错能力来看,它所不能发现的错误的几率仅为0.0047%以下。

    从性能上和开销上考虑,均远远优于奇偶校验及算术和校验等方式。

    因而,在数据存储和数据通讯领域,CRC无处不在:著名的通讯协议X.25的FCS(帧检错序列)采用的是CRC-CCITT,WinRAR、NERO、ARJ、LHA等压缩工具软件采用的是CRC32,磁盘驱动器的读写采用了CRC16,通用的图像存储格式GIF、TIFF等也都用CRC作为检错手段。

    二、CRC名称的定义

    这里需要知道几个组成部分或者说计算概念:多项式公式、多项式简记式、数据宽度、初始值、结果异或值、输入值反转、输出值反转、参数模型。

    1、多项式公式

    对于CRC标准除数,一般使用多项式(或二项式)公式表示,如下图中除数11011(poly值为0x1b)的二项式为G(X)=X4+X3+X+1,X的指数就代表了该bit位上的数据为1,(最低位为0)。

    这里特别注意一下位数问题,除数的位数为二项式最高次幂+1(4+1=5),这个很重要。

    2、多项式简记式

    通过对CRC的基本了解我们知道,多项式的首尾必定为1,而这个1的位置在下一步计算一定为0,所以就把前面这个1给省略掉了,出现了一个叫简记式的东西,如上例中除数11011的简记式为1011,很多看过CRC高级语言源码的人会知道,对于CRC_16标准下G(X)=X16+X15+X2+1(16#18005)的poly值实际上是8005,这里使用的就是简记式。后面会对这个用法做一个说明。

    3、数据宽度

    数据宽度指的就是CRC校验码的长度(二进制位数),知道了CRC的运算概念和多项式,就可以理解这个概念了,CRC长度始终要比除数位数少1,与简记式长度是一致的。

    以上三个数据就是我们经常能够用到的基本数据

    4、初始值与结果异或值

    在一些标准中,规定了初始值,则数据在进行上述二项式运算之前,需要先将要计算的数据与初始值的最低字节进行异或,然后再与多项式进行计算。

    而在结果异或值不为零的情况下,则需要将计算得到的CRC结果值再与结果异或值进行一次异或计算,得到的最终值才是我们需要的CRC校验码。

    这里可以看出,初始值与结果值的位数要求与数据宽度一致。

    5、输入值反转与输出值反转

    输入值反转的意思是在计算之前先将二项式反转,然后再用得到的新值和数据进行计算。如对于G(X)=X16+X15+X2+1(16#18005),其正向值为1 1000 0000 0000 0101,反转值则为1010 0000 0000 0001 1

    输出值反转则是将最终得到的CRC结果反转。

    通常,输入值反转后的结果值也会是反转的,所以这两个选项一般是同向的,我们只有在在线CRC计算器中会看到自由选择正反转的情况存在。

    三、常见的CRC算法

    虽然CRC可以任意定义二项式、数据长度等,但没有一个统一的标准的话,就会让整个计算变得非常的麻烦。但实际上,不同的厂家经常采用不同的标准算法,这里列出了一些国际常用的模型表:

    名称多项式表示法应用举例
    CRC-8X8+X2+X+10X107
    CRC-12X12+X11+X3+X2+X+10X180Ftelecom systems
    CRC-16X16+X15+X2+10X18005Bisync, Modbus, USB, ANSI X3.28, SIA DC-07, many others; also known as CRC-16 and CRC-16-ANSI
    CRC-CCITTX16+X12+X5+10X11021ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
    CRC-32X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+10x104C11DB7ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCS
    CRC-32CX32+X28+X27+X26+X25+X23+X22+X20+X19+X18+X14+X13+X11+X10+X9+X8+X6+10x11EDC6F41iSCSI, SCTP, G.hn payload, SSE4.2, Btrfs, ext4, Ceph

    四、CRC校验算法前置知识

    在学习CRC校验算法之前,先复习一下CRC会涉及的主要几个主要的算法。

    1. 异或

    异或,就是不同为1,相同为0,运算符号是^。

    0^0 = 0
    0^1 = 1
    1^1 = 0
    1^0 = 1
    

    异或运算存在如下几个规律,需要了解。

    0^x = x 即0 异或任何数等于任何数
    1^x = ~x 即1异或任何数等于任何数取反
    x^x = 0 即任何数与自己异或,结果为0
    a ^ b = b ^ a 交换律
    a ^ (b ^ c) = (a ^ b) ^c 结合律
    

    2. 模2加法

    模2加法相对于普通的算术加法,主要的区别在模2加法,不做进位处理。具体结果如下。0+0 = 0 0+1 = 1 1+1 = 0 1+0 = 1 我们发现模2加法的计算结果,同异或运算结果一模一样。进一步推演,我们会发现,异或运算的5个规律,同样适合于模2加法。这里,就不在一一列举了。

    3. 模2减法

    模2减法相对于普通的算术减法,主要的区别在模2减法,不做借位处理。具体结果如下。0-0 = 0 0-1 = 1 1-1 = 0 1-0 = 1 我们发现模2减法的计算结果,同模2加法,以及异或的运算结果一模一样。进一步推演,我们会发现,异或运算的5个规律,同样适合于模2减法。这里,就不在一一列举了。

    4. 模2除法

    模2除法相对于普通的算术除法,主要的区别在模2除法,它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。

    五、CRC原理

    CRC原理:在K位信息码(目标发送数据)后再拼接R位校验码,使整个编码长度为N位,因此这种编码也叫(N,K)码。

    通俗的说,就是在需要发送的信息后面附加一个数(即校验码),生成一个新的发送数据发送给接收端。这个数据要求能够使生成的新数据被一个特定的数整除。这里的整除需要引入模 2除法的概念。

    那么,CRC校验的具体做法就是

    (1)选定一个标准除数(K位二进制数据串)

    (2)在要发送的数据(m位)后面加上K-1位0,然后将这个新数(M+K-1位)以模2除法的方式除以上面这个标准除数,所得到的余数也就是该数据的CRC校验码(注:余数必须比除数少且只少一位,不够就补0)

    (3)将这个校验码附在原m位数据后面,构成新的M+K-1位数据,发送给接收端。

    (4)接收端将接收到的数据除以标准除数,如果余数为0则认为数据正确。

    注意:CRC校验中有两个关键点:

    一是要预先确定一个发送端和接收端都用来作为除数的二进制比特串(或多项式);

    二是把原始帧与上面选定的除进行二进制除法运算,计算出FCS。

    前者可以随机选择,也可按国际上通行的标准选择,但最高位和最低位必须均为“1”

    六、循环冗余的计算

    实例:

    由于CRC-32、CRC-16、CCITT和CRC-4的编码过程基本一致,只有位数和生成多项式不一样,下面就举例,来说明CRC校验码生成过程。

    对于数据1110 0101(16#E5),以指定除数11011求它的CRC校验码,其过程如下:

    使用上面计算的校验和和消息数据,可以创建要传输的码字。

    有时候,我们需要填充checksum到制定的位置,这就涉及到字节序问题,建议用memcpy()进行拷贝。

    七、代码实现

    实现算法参考网络相关代码,进行整理并验证,可直接使用。crc.c

    /*  
     *一口Linux
     *2021.6.21
     *version: 1.0.0
    */
    #include "crc.h"
    #include <stdio.h>
    
    typedef enum {
     REF_4BIT = 4,
     REF_5BIT = 5,
     REF_6BIT = 6,
     REF_7BIT = 7,
     REF_8BIT = 8,
     REF_16BIT = 16,
     REF_32BIT = 32
    }REFLECTED_MODE;
    
    uint32_t ReflectedData(uint32_t data, REFLECTED_MODE mode)
    {
     data = ((data & 0xffff0000) >> 16) | ((data & 0x0000ffff) << 16);
     data = ((data & 0xff00ff00) >> 8) | ((data & 0x00ff00ff) << 8);
     data = ((data & 0xf0f0f0f0) >> 4) | ((data & 0x0f0f0f0f) << 4);
     data = ((data & 0xcccccccc) >> 2) | ((data & 0x33333333) << 2);
     data = ((data & 0xaaaaaaaa) >> 1) | ((data & 0x55555555) << 1);
    
     switch (mode)
     {
     case REF_32BIT:
      return data;
     case REF_16BIT:
      return (data >> 16) & 0xffff;
     case REF_8BIT:
      return (data >> 24) & 0xff;
     case REF_7BIT:
      return (data >> 25) & 0x7f;
     case REF_6BIT:
      return (data >> 26) & 0x7f;
     case REF_5BIT:
      return (data >> 27) & 0x1f;
     case REF_4BIT:
      return (data >> 28) & 0x0f;
     }
     return 0;
    }
    
    uint8_t CheckCrc4(uint8_t poly, uint8_t init, bool refIn, bool refOut, uint8_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint8_t i;
     uint8_t crc;
    
     if (refIn == true)
     {
      crc = init;
      poly = ReflectedData(poly, REF_4BIT);
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x01)
        {
         crc >>= 1;
         crc ^= poly;
        }
        else
        {
         crc >>= 1;
        }
       }
      }
    
      return crc ^ xorOut;
     }
     else
     {
      crc = init << 4;
      poly <<= 4;
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x80)
        {
         crc <<= 1;
         crc ^= poly;
        }
        else
        {
         crc <<= 1;
        }
       }
      }
    
      return (crc >> 4) ^ xorOut;
     }
    }
    
    uint8_t CheckCrc5(uint8_t poly, uint8_t init, bool refIn, bool refOut, uint8_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint8_t i;
     uint8_t crc;
    
     if (refIn == true)
     {
      crc = init;
      poly = ReflectedData(poly, REF_5BIT);
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x01)
        {
         crc >>= 1;
         crc ^= poly;
        }
        else
        {
         crc >>= 1;
        }
       }
      }
    
      return crc ^ xorOut;
     }
     else
     {
      crc = init << 3;
      poly <<= 3;
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x80)
        {
         crc <<= 1;
         crc ^= poly;
        }
        else
        {
         crc <<= 1;
        }
       }
      }
    
      return (crc >> 3) ^ xorOut;
     }
    }
    
    uint8_t CheckCrc6(uint8_t poly, uint8_t init, bool refIn, bool refOut, uint8_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint8_t i;
     uint8_t crc;
    
     if (refIn == true)
     {
      crc = init;
      poly = ReflectedData(poly, REF_6BIT);
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x01)
        {
         crc >>= 1;
         crc ^= poly;
        }
        else
        {
         crc >>= 1;
        }
       }
      }
    
      return crc ^ xorOut;
     }
     else
     {
      crc = init << 2;
      poly <<= 2;
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x80)
        {
         crc <<= 1;
         crc ^= poly;
        }
        else
        {
         crc <<= 1;
        }
       }
      }
    
      return (crc >> 2) ^ xorOut;
     }
    }
    
    uint8_t CheckCrc7(uint8_t poly, uint8_t init, bool refIn, bool refOut, uint8_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint8_t i;
     uint8_t crc;
    
     if (refIn == true)
     {
      crc = init;
      poly = ReflectedData(poly, REF_7BIT);
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x01)
        {
         crc >>= 1;
         crc ^= poly;
        }
        else
        {
         crc >>= 1;
        }
       }
      }
    
      return crc ^ xorOut;
     }
     else
     {
      crc = init << 1;
      poly <<= 1;
    
      while (length--)
      {
       crc ^= *buffer++;
       for (i = 0; i < 8; i++)
       {
        if (crc & 0x80)
        {
         crc <<= 1;
         crc ^= poly;
        }
        else
        {
         crc <<= 1;
        }
       }
      }
    
      return (crc >> 1) ^ xorOut;
     }
    }
    
    uint8_t CheckCrc8(uint8_t poly, uint8_t init, bool refIn, bool refOut, uint8_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint32_t i = 0;
     uint8_t crc = init;
    
     while (length--)
     {
      if (refIn == true)
      {
       crc ^= ReflectedData(*buffer++, REF_8BIT);
      }
      else
      {
       crc ^= *buffer++;
      }
    
      for (i = 0; i < 8; i++)
      {
       if (crc & 0x80)
       {
        crc <<= 1;
        crc ^= poly;
       }
       else
       {
        crc <<= 1;
       }
      }
     }
    
     if (refOut == true)
     {
      crc = ReflectedData(crc, REF_8BIT);
     }
    
     return crc ^ xorOut;
    }
    
    uint16_t CheckCrc16(uint16_t poly, uint16_t init, bool refIn, bool refOut, uint16_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint32_t i = 0;
     uint16_t crc = init;
    
     while (length--)
     {
      if (refIn == true)
      {
       crc ^= ReflectedData(*buffer++, REF_8BIT) << 8;
      }
      else
      {
       crc ^= (*buffer++) << 8;
      }
    
      for (i = 0; i < 8; i++)
      {
       if (crc & 0x8000)
       {
        crc <<= 1;
        crc ^= poly;
       }
       else
       {
        crc <<= 1;
       }
      }
     }
    
     if (refOut == true)
     {
      crc = ReflectedData(crc, REF_16BIT);
     }
    
     return crc ^ xorOut;
    }
    
    uint32_t CheckCrc32(uint32_t poly, uint32_t init, bool refIn, bool refOut, uint32_t xorOut,
     const uint8_t *buffer, uint32_t length)
    {
     uint32_t i = 0;
     uint32_t crc = init;
    
     while (length--)
     {
      if (refIn == true)
      {
       crc ^= ReflectedData(*buffer++, REF_8BIT) << 24;
      }
      else
      {
       crc ^= (*buffer++) << 24;
      }
    
      for (i = 0; i < 8; i++)
      {
       if (crc & 0x80000000)
       {
        crc <<= 1;
        crc ^= poly;
       }
       else
       {
        crc <<= 1;
       }
      }
     }
    
     if (refOut == true)
     {
      crc = ReflectedData(crc, REF_32BIT);
     }
    
     return crc ^ xorOut;
    }
    
    uint32_t CrcCheck(CRC_Type crcType, const uint8_t *buffer, uint32_t length)
    {
     switch (crcType.width)
     {
     case 4:
      return CheckCrc4(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 5:
      return CheckCrc5(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 6:
      return CheckCrc6(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 7:
      return CheckCrc7(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 8:
      return CheckCrc8(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 16:
      return CheckCrc16(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     case 32:
      return CheckCrc32(crcType.poly, crcType.init, crcType.refIn, crcType.refOut,
       crcType.xorOut, buffer, length);
     }
     return 0;
    }
    
    

    crc.h

    /*  
     *一口Linux
     *2021.6.21
     *version: 1.0.0
    */
    #ifndef __CRC_H__
    #define __CRC_H__
    
    #include <stdint.h>
    #include <stdbool.h>
    
    typedef struct {
     uint8_t width;
     uint32_t poly;
     uint32_t init;
     bool refIn;
     bool refOut;
     uint32_t xorOut;
    }CRC_Type;
    
    uint32_t CrcCheck(CRC_Type crcType, const uint8_t *buffer, uint32_t length);
    
    #endif
    

    main.c

    /*  
     *一口Linux
     *2021.6.21
     *version: 1.0.0
    */
    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include "crc.h"
    
    #define LENGTH 8
    const uint8_t data[3][LENGTH] = {
     { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
     { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
     { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f }};
    
    typedef struct {
     CRC_Type crcType;
     uint32_t result[3];
    }CRC_Test;
    
    CRC_Test crc4_ITU = { { 4, 0x03, 0x00, true, true, 0x00 }, { 0x0f, 0x0a, 0x0e } };
    CRC_Test crc5_EPC = { { 5, 0x09, 0x09, false, false, 0x00 }, { 0x00, 0x0c, 0x17 } };
    CRC_Test crc5_ITU = { { 5, 0x15, 0x00, true, true, 0x00 }, { 0x16, 0x0a, 0x17 } };
    CRC_Test crc5_USB = { { 5, 0x05, 0x1f, true, true, 0x1f }, { 0x10, 0x09, 0x17 } };
    CRC_Test crc6_ITU = { { 6, 0x03, 0x00, true, true, 0x00 }, { 0x1d, 0x30, 0x00 } };
    CRC_Test crc7_MMC = { { 7, 0x09, 0x00, false, false, 0x00 }, { 0x57, 0x30, 0x5b } };
    CRC_Test crc8 = { { 8, 0x07, 0x00, false, false, 0x00 }, { 0x3e, 0xe1, 0x36 } };
    CRC_Test crc8_ITU = { { 8, 0x07, 0x00, false, false, 0x55 }, { 0x6b, 0xb4, 0x63 } };
    CRC_Test crc8_ROHC = { { 8, 0x07, 0xff, true, true, 0x00 }, { 0x6b, 0x78, 0x93 } };
    CRC_Test crc8_MAXIM = { { 8, 0x31, 0x00, true, true, 0x00 }, { 0x83, 0x60, 0xa9 } };
    CRC_Test crc16_IBM = { { 16, 0x8005, 0x0000, true, true, 0x0000 }, { 0xc4f0, 0x2337, 0xa776 } };
    CRC_Test crc16_MAXIM = { { 16, 0x8005, 0x0000, true, true, 0xffff }, { 0x3b0f, 0xdcc8, 0x5889 } };
    CRC_Test crc16_USB = { { 16, 0x8005, 0xffff, true, true, 0xffff }, { 0x304f, 0xd788, 0x53c9 } };
    CRC_Test crc16_MODBUS = { { 16, 0x8005, 0xffff, true, true, 0x0000 }, { 0xcfb0, 0x2877, 0xac36 } };
    CRC_Test crc16_CCITT = { { 16, 0x1021, 0x0000, true, true, 0x0000 }, { 0xeea7, 0xfe7c, 0x7919 } };
    CRC_Test crc16_CCITT_FALSE = { { 16, 0x1021, 0xffff, false, false, 0x0000 }, { 0x4792, 0x13a7, 0xb546 } };
    CRC_Test crc16_X25 = { { 16, 0x1021, 0xffff, true, true, 0xffff }, { 0x6dd5, 0x7d0f, 0xfa6a } };
    CRC_Test crc16_XMODEM = { { 16, 0x1021, 0x0000, false, false, 0x0000 }, { 0x76ac, 0x2299, 0x8478 } };
    CRC_Test crc16_DNP = { { 16, 0x3D65, 0x0000, true, true, 0xffff }, { 0x7bda, 0x0535, 0x08c4 } };
    CRC_Test crc32 = { { 32, 0x04c11db7, 0xffffffff, true, true, 0xffffffff }, { 0x3fca88c5, 0xe0631a53, 0xa4051a26 } };
    CRC_Test crc32_MPEG2 = { { 32, 0x4c11db7, 0xffffffff, false, false, 0x00000000 }, { 0x14dbbdd8, 0x6509b4b6, 0xcb09d294 } };
    
    void CrcTest(CRC_Test crcTest)
    {
     uint32_t i;
     for (i = 0; i < 3; i++)
     {
      printf("%08x\t%08x\r\n", CrcCheck(crcTest.crcType, data[i], LENGTH), crcTest.result[i]);
     }
     printf("\r\n");
    }
    
    int main(void)
    {
     CrcTest(crc4_ITU);
     CrcTest(crc5_EPC);
     CrcTest(crc5_ITU);
     CrcTest(crc5_USB);
     CrcTest(crc6_ITU);
     CrcTest(crc7_MMC);
     CrcTest(crc8);
     CrcTest(crc8_ITU);
     CrcTest(crc8_ROHC);
     CrcTest(crc8_MAXIM);
     CrcTest(crc16_IBM);
     CrcTest(crc16_MAXIM);
     CrcTest(crc16_USB);
     CrcTest(crc16_MODBUS);
     CrcTest(crc16_CCITT);
     CrcTest(crc16_CCITT_FALSE);
     CrcTest(crc16_X25);
     CrcTest(crc16_XMODEM);
     CrcTest(crc16_DNP);
     CrcTest(crc32);
     CrcTest(crc32_MPEG2);
    
     return 0;
    }
    
    

    注意

    不同的CRC算法,对00H或FFH数据流的计算结果不一样,部分算法存在校验结果也为00H或FFH的情况(也就意味着存储空间处于初始化状态时:全0或全1,CRC校验反而是正确的),在应用中需要注意避免。

    ------------ END ------------


    ●嵌入式专栏精选教程

    ●精选汇总 | ST工具、下载编程工具

    ●精选汇总 | 嵌入式软件设计与开发

    ●精选汇总 | STM32、MCU、单片机

    迎关注我的公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

    欢迎关注我的视频号:

    点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

    展开全文
  • 用软件实现 CRC 校验码计算很难满足高速数据通信的要求 ,基于硬件的实现方法中 ,有串行经典算法 LFSR 电路 以及由软件算法推导出来的其它各种并行计算方法。以经典的LFSR 电路为基础 ,研究了按字节并行计算 CRC 校验...
  • 计算CRC16的工具及源代码,vc2019解决方案,可以把待计算部分的通道(十六进制,空格隔开,比如 68 04 00 04 00 68 12 34 56)直接复制到文本框,计算即可.
  • 计算CRC冗余校验码(32)

    2017-02-17 14:26:37
    计算CRC 校验码 计算机网络
  • C语言CRC16计算代码

    2016-12-06 17:04:31
    已验证可用的CRC16计算代码,下载可用
  • C# CRC 16 校验码生成

    2019-04-17 11:24:39
    1.C# CRC 16 校验码生成源码; 2.CRC-16 MODBUG; 3.C#写的CRC16检验算法;
  • crc7.h #ifndef CRC7_H #define CRC7_H /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" /* Private function prototypes ---------------------...

     前言

    CRC校验码其实很简单,详细的去网上查,我这里就简单讲讲

    CRC校验码简介

    crc校验码其实就是对数据进行模二除法的得出来的余数(模二除法上网查)

    模二除法的被除数是数据,除数是校验码对应的多项式

    代码如果按照我们手算模二除法的顺序算,会很麻烦,那么代码就会用到模二加法

    就是按字节,做模二除法取余数,然后结果加上下一个字节,以此类推

    这个是重中之重,很多人看不懂代码到底是什么意思,因为模二加法和模二除法在编程中就是异或操作

    代码

    crc7.h

    #ifndef CRC7_H
    #define CRC7_H
    /* Includes ------------------------------------------------------------------*/
    #include "stm32f4xx_hal.h"
    
    /* Private function prototypes -----------------------------------------------*/
    void Append_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length);//附加CRC7校验码(reserved)
    uint32_t Verify_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length, uint8_t CRC7);//核实CRC7校验码
    uint8_t Get_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length, uint8_t CRC7 );//获得CRC7校验码
    
    #endif
    

    crc7.c

    /* Includes ------------------------------------------------------------------*/
    #include "CRC7.h"
    
    /* Private variables ---------------------------------------------------------*/
    /* ~CRC7计算基本信息 */
    //crc7 generator polynomial : G(x)=x7+x3+1
    const uint8_t CRC7_INIT = 0x00;
    const uint8_t CRC7_TAB[256] = 
    {//16x16
    0X00, 0X09, 0X12, 0X1B, 0X24, 0X2D, 0X36, 0X3F, 0X48, 0X41, 0X5A, 0X53, 0X6C, 0X65, 0X7E, 0X77,
    0X19, 0X10, 0X0B, 0X02, 0X3D, 0X34, 0X2F, 0X26, 0X51, 0X58, 0X43, 0X4A, 0X75, 0X7C, 0X67, 0X6E,
    0X32, 0X3B, 0X20, 0X29, 0X16, 0X1F, 0X04, 0X0D, 0X7A, 0X73, 0X68, 0X61, 0X5E, 0X57, 0X4C, 0X45,
    0X2B, 0X22, 0X39, 0X30, 0X0F, 0X06, 0X1D, 0X14, 0X63, 0X6A, 0X71, 0X78, 0X47, 0X4E, 0X55, 0X5C,
    0X64, 0X6D, 0X76, 0X7F, 0X40, 0X49, 0X52, 0X5B, 0X2C, 0X25, 0X3E, 0X37, 0X08, 0X01, 0X1A, 0X13,
    0X7D, 0X74, 0X6F, 0X66, 0X59, 0X50, 0X4B, 0X42, 0X35, 0X3C, 0X27, 0X2E, 0X11, 0X18, 0X03, 0X0A,
    0X56, 0X5F, 0X44, 0X4D, 0X72, 0X7B, 0X60, 0X69, 0X1E, 0X17, 0X0C, 0X05, 0X3A, 0X33, 0X28, 0X21,
    0X4F, 0X46, 0X5D, 0X54, 0X6B, 0X62, 0X79, 0X70, 0X07, 0X0E, 0X15, 0X1C, 0X23, 0X2A, 0X31, 0X38,
    0X41, 0X48, 0X53, 0X5A, 0X65, 0X6C, 0X77, 0X7E, 0X09, 0X00, 0X1B, 0X12, 0X2D, 0X24, 0X3F, 0X36,
    0X58, 0X51, 0X4A, 0X43, 0X7C, 0X75, 0X6E, 0X67, 0X10, 0X19, 0X02, 0X0B, 0X34, 0X3D, 0X26, 0X2F,
    0X73, 0X7A, 0X61, 0X68, 0X57, 0X5E, 0X45, 0X4C, 0X3B, 0X32, 0X29, 0X20, 0X1F, 0X16, 0X0D, 0X04,
    0X6A, 0X63, 0X78, 0X71, 0X4E, 0X47, 0X5C, 0X55, 0X22, 0X2B, 0X30, 0X39, 0X06, 0X0F, 0X14, 0X1D,
    0X25, 0X2C, 0X37, 0X3E, 0X01, 0X08, 0X13, 0X1A, 0X6D, 0X64, 0X7F, 0X76, 0X49, 0X40, 0X5B, 0X52,
    0X3C, 0X35, 0X2E, 0X27, 0X18, 0X11, 0X0A, 0X03, 0X74, 0X7D, 0X66, 0X6F, 0X50, 0X59, 0X42, 0X4B,
    0X17, 0X1E, 0X05, 0X0C, 0X33, 0X3A, 0X21, 0X28, 0X5F, 0X56, 0X4D, 0X44, 0X7B, 0X72, 0X69, 0X60,
    0X0E, 0X07, 0X1C, 0X15, 0X2A, 0X23, 0X38, 0X31, 0X46, 0X4F, 0X54, 0X5D, 0X62, 0X6B, 0X70, 0X79,
    };
    /* CRC7计算基本信息~ */
    
    /* Private user code ---------------------------------------------------------*/
    /*
    ** Descriptions: append CRC7 to the end of data (reserved)
    ** Input: Data to Append, Stream length = Data + checksum
    ** Output: 
    */
    void Append_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length)
    {//reserved
    }
    
    /* Completed user code -------------------------------------------------------*/
    /*
    ** Descriptions: CRC7 Verify function
    ** Input: Data to Verify, Stream length = Data, CRC7 to Verify
    ** Output: True or False (CRC Verify Result)
    ** Explain: 通过(*pchMessage)求得CRC7校验码并与(CRC7)对比
    */
    uint32_t Verify_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length, uint8_t CRC7)
    {
    	uint8_t Expected;
    	
    	if (pchMessage == NULL || Length < 2)		//if (pchMessage == 0 || dwLength <= 2)
    	{
    		return 0;
    	}
    	
    	Expected = Get_CRC7_Check_Sum( pchMessage, Length, CRC7_INIT);
    	
    	return ( Expected == CRC7 );
    }
    
    /*
    ** Descriptions: Get CRC7 function
    ** Input: Data to get CRC7, Stream length = Data, CRC7_INIT
    ** Output: CRC7
    ** Explain: 通过(*pchMessage)求得(CRC7)
    */
    uint8_t Get_CRC7_Check_Sum( uint8_t *pchMessage, uint16_t Length, uint8_t CRC7 )
    {
    	uint8_t crc, index;
    	crc = CRC7;
    	
    	while(Length--)
    	{
    		index = crc ^ (*pchMessage);				//crc + 数据(模二加法)
    		pchMessage++;								//数据指针右移
    		crc = CRC7_TAB[index];						//对index求余(模二除法,查表)
    	}
    	
    	return crc;
    }

    展开全文
  • 内容索引:Delphi源码,算法相关,算法,CRC 内含8位、16位、32位的CRC校验算法示例代码,生成多项式的值(多项式因子)  注意:CRC16是数据流的高位先计算,多项式因子不变  而CRC32和CRC8都是数据流的低位先计算,...
  • 各种CRC校验计算源码

    2018-09-23 09:27:56
    各种CRC16计算代码,包括AX25、CCIT、IBM、MAXIM、ModBus等计算源码,以及CRC32
  • CRC校验码labview指令

    2018-04-21 10:29:37
    串口通讯需要CRC校验码,labview代码自动根据前面代码计算CRC校验码,得到完整的串口通讯指令
  • 目录一、前言二、代码示例CRC4CRC5CRC6...这是我第一次转载别人的文章,因为觉得这篇博客的代码写的挺好的,很实用,所以就推荐给大家,如果你们在项目中正好需要用到crc校验的话没必要自己浪费时间去写,可以直接到...

    一、前言

    特别说明:本文转载于https://blog.csdn.net/leumber/article/details/54311811

    这是我第一次转载别人的文章,因为觉得这篇博客的代码写的挺好的,很实用,所以就推荐给大家,如果你们在项目中正好需要用到crc校验的话没必要自己浪费时间去写,可以直接到这里拷贝代码片段快速加入到自己的程序里面。
    关于crc校验的原理我就不说了,感兴趣的同学可以去原文看一下,我这里只贴上代码片段。

    二、代码示例

    CRC4

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    /****************************Info********************************************** 
     * Name:    CRC-4/ITU	x4+x+1 
     * Width:	4
     * Poly:    0x03 
     * Init:    0x00 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
    unsigned char CRC4_ITU(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x03;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly << 4);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    

    CRC5

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    /****************************Info********************************************** 
     * Name:    CRC-5/EPC	x5+x3+1 
     * Width:	5
     * Poly:    0x09 
     * Init:    0x09 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
    unsigned char CRC5_EPC(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x09<<3;
    	unsigned char wCPoly = 0x09<<3;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin >> 3);
    }
    /****************************Info********************************************** 
     * Name:    CRC-5/USB	x5+x2+1 
     * Width:	5
     * Poly:    0x05 
     * Init:    0x1F 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x1F 
     * Note: 
     *****************************************************************************/
    #if 0
    unsigned char CRC5_USB(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x1F<<3;
    	unsigned char wCPoly = 0x05;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly << 3);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin^0x1F);
    }
    #else
    unsigned char CRC5_USB(unsigned char *data, unsigned int datalen)  
    {  
    	unsigned char wCRCin = 0x1F;
    	unsigned char wCPoly = 0x05;
    	
    	InvertUint8(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ (wCPoly >> 3);
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin^0x1F); 
    } 
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-5/ITU	x5+x4+x2+1  
     * Width:	5
     * Poly:    0x15 
     * Init:    0x00 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
     #if 0
    unsigned char CRC5_ITU(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x15;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly << 3);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else
    unsigned char CRC5_ITU(unsigned char *data, unsigned int datalen)  
    {  
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x15;
    	
    	InvertUint8(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ (wCPoly >> 3);
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin); 
    } 
    #endif
    

    CRC6

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    /****************************Info********************************************** 
     * Name:    CRC-6/ITU	x6+x+1 
     * Width:	6
     * Poly:    0x03 
     * Init:    0x00 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
    unsigned char CRC6_ITU(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x03;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly << 2);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    

    CRC7

    /****************************Info********************************************** 
     * Name:    CRC-7/MMC           x7+x3+1  
     * Width:	7
     * Poly:    0x09 
     * Init:    0x00 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x00 
     * Use:     MultiMediaCard,SD,ect. 
     *****************************************************************************/
    unsigned char CRC7_MMC(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x09;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ (wCPoly<<1);
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin>>1);
    }
    

    CRC8

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    /****************************Info********************************************** 
     * Name:    CRC-8               x8+x2+x+1 
     * Width:	8 
     * Poly:    0x07 
     * Init:    0x00 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
    unsigned char CRC8(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x07;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin);
    }
    /****************************Info********************************************** 
     * Name:    CRC-8/ITU           x8+x2+x+1 
     * Width:	8 
     * Poly:    0x07 
     * Init:    0x00 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x55 
     * Alias:   CRC-8/ATM 
     *****************************************************************************/
    unsigned char CRC8_ITU(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x07;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin^0x55);
    }
    /****************************Info********************************************** 
     * Name:    CRC-8/ROHC          x8+x2+x+1 
     * Width:	8 
     * Poly:    0x07 
     * Init:    0xFF 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x00 
     * Note: 
     *****************************************************************************/
    #if 0
    unsigned char CRC8_ROHC(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0xFF;
    	unsigned char wCPoly = 0x07;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 0);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else 
    unsigned char CRC8_ROHC(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0xFF;
    	unsigned char wCPoly = 0x07;
    	
    	InvertUint8(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-8/MAXIM         x8+x5+x4+1 
     * Width:	8 
     * Poly:    0x31 
     * Init:    0x00 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x00 
     * Alias:   DOW-CRC,CRC-8/IBUTTON 
     * Use:     Maxim(Dallas)'s some devices,e.g. DS18B20 
     *****************************************************************************/ 
    #if 0
    unsigned char CRC8_MAXIM(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x31;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 0);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint8(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else 
    unsigned char CRC8_MAXIM(unsigned char *data, unsigned int datalen)
    {
    	unsigned char wCRCin = 0x00;
    	unsigned char wCPoly = 0x31;
    	
    	InvertUint8(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin);
    }
    #endif
    

    CRC16

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    void InvertUint16(unsigned short *dBuf,unsigned short *srcBuf)
    {
    	int i;
    	unsigned short tmp[4]={0};
     
    	for(i=0;i< 16;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(15 - i);
    	}
    	dBuf[0] = tmp[0];
    }
    /****************************Info********************************************** 
     * Name:    CRC-16/CCITT        x16+x12+x5+1 
     * Width:	16
     * Poly:    0x1021 
     * Init:    0x0000 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x0000 
     * Alias:   CRC-CCITT,CRC-16/CCITT-TRUE,CRC-16/KERMIT 
     *****************************************************************************/ 
    #if 0
    unsigned short CRC16_CCITT(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x1021;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else 
    //这里为了效率,我们不需要将所有Refin和refout为true的输入输出数据移位转换
    //只需要将poly二项式转换后,运算时将左移变为右移
    unsigned short CRC16_CCITT(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x1021;
    	unsigned char wChar = 0;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/CCITT-FALSE   x16+x12+x5+1 
     * Width:	16 
     * Poly:    0x1021 
     * Init:    0xFFFF 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x0000 
     * Note: 
     *****************************************************************************/ 
    unsigned short CRC16_CCITT_FALSE(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x1021;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++) << 8;
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin);
    }
    /****************************Info********************************************** 
     * Name:    CRC-16/XMODEM       x16+x12+x5+1 
     * Width:	16 
     * Poly:    0x1021 
     * Init:    0x0000 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x0000 
     * Alias:   CRC-16/ZMODEM,CRC-16/ACORN 
     *****************************************************************************/ 
    unsigned short CRC16_XMODEM(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x1021;
    	
    	while (datalen--) 	
    	{
    		wCRCin ^= (*(data++) << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin);
    }
    /****************************Info********************************************** 
     * Name:    CRC-16/X25          x16+x12+x5+1 
     * Width:	16 
     * Poly:    0x1021 
     * Init:    0xFFFF 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0XFFFF 
     * Note: 
     *****************************************************************************/
    #if 0 
    unsigned short CRC16_X25(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x1021;
    	unsigned char wChar = 0;
     
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin^0xFFFF);
    }
    #else 
    unsigned short CRC16_X25(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x1021;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin^0xFFFF);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/MODBUS       x16+x15+x2+1 
     * Width:	16 
     * Poly:    0x8005 
     * Init:    0xFFFF 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x0000 
     * Note: 
     *****************************************************************************/
    #if 0 
    unsigned short CRC16_MODBUS(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x8005;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else 
    unsigned short CRC16_MODBUS(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x8005;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/IBM          x16+x15+x2+1 
     * Width:	16 
     * Poly:    0x8005 
     * Init:    0x0000 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0x0000 
     * Alias:   CRC-16,CRC-16/ARC,CRC-16/LHA 
     *****************************************************************************/ 
    #if 0
    unsigned short CRC16_IBM(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x8005;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin);
    }
    #else 
    unsigned short CRC16_IBM(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x8005;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/MAXIM        x16+x15+x2+1 
     * Width:	16 
     * Poly:    0x8005 
     * Init:    0x0000 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0xFFFF 
     * Note: 
     *****************************************************************************/
    #if 0
    unsigned short CRC16_MAXIM(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x8005;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin^0xFFFF);
    }
    #else 
    unsigned short CRC16_MAXIM(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x8005;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin^0xFFFF);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/USB          x16+x15+x2+1 
     * Width:	16 
     * Poly:    0x8005 
     * Init:    0xFFFF 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0xFFFF 
     * Note: 
     *****************************************************************************/ 
    #if 0
    unsigned short CRC16_USB(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x8005;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin^0xFFFF);
    }
    #else 
    unsigned short CRC16_USB(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0xFFFF;
    	unsigned short wCPoly = 0x8005;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin^0xFFFF);
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-16/DNP          x16+x13+x12+x11+x10+x8+x6+x5+x2+1 
     * Width:	16 
     * Poly:    0x3D65 
     * Init:    0x0000 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0xFFFF 
     * Use:     M-Bus,ect. 
     *****************************************************************************/  
    #if 0
    unsigned short CRC16_DNP(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x3D65;
    	unsigned char wChar = 0;
    	
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8(&wChar,&wChar);
    		wCRCin ^= (wChar << 8);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x8000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint16(&wCRCin,&wCRCin);
    	return (wCRCin^0xFFFF) ;
    }
    #else
    unsigned short CRC16_DNP(unsigned char *data, unsigned int datalen)
    {
    	unsigned short wCRCin = 0x0000;
    	unsigned short wCPoly = 0x3D65;
    	
    	InvertUint16(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = (wCRCin >> 1);
    		}
    	}
    	return (wCRCin^0xFFFF);
    }
    #endif
    

    CRC32

    /****************************Info********************************************** 
     * Name:    InvertUint8 
     * Note: 	把字节颠倒过来,如0x12变成0x48
    			0x12: 0001 0010
    			0x48: 0100 1000
     *****************************************************************************/
    void InvertUint8(unsigned char *dBuf,unsigned char *srcBuf)
    {
    	int i;
    	unsigned char tmp[4]={0};
     
    	for(i=0;i< 8;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(7-i);
    	}
    	dBuf[0] = tmp[0];
    	
    }
    void InvertUint32(unsigned int *dBuf,unsigned int *srcBuf)
    {
    	int i;
    	unsigned int tmp[4]={0};
    	
    	for(i=0;i< 32;i++)
    	{
    		if(srcBuf[0]& (1 << i))
    		tmp[0]|=1<<(31 - i);
    	}
    	dBuf[0] = tmp[0];
    }
    /****************************Info********************************************** 
     * Name:    CRC-32  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 
     * Width:	32 
     * Poly:    0x4C11DB7 
     * Init:    0xFFFFFFF 
     * Refin:   True 
     * Refout:  True 
     * Xorout:  0xFFFFFFF 
     * Alias:   CRC_32/ADCCP 
     * Use:     WinRAR,ect. 
     *****************************************************************************/  
    #if 0
    unsigned int CRC32(unsigned char *data, unsigned int datalen)
    {
    	unsigned int wCRCin = 0xFFFFFFFF;
    	unsigned int wCPoly = 0x04C11DB7;
    	unsigned int wChar = 0;
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		InvertUint8((unsigned char *)&wChar,(unsigned char *)&wChar);
    		wCRCin ^= (wChar << 24);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80000000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	InvertUint32(&wCRCin,&wCRCin);
    	return (wCRCin ^ 0xFFFFFFFF) ;
    }
    #else
    unsigned int CRC32(unsigned char *data, unsigned int datalen)
    {
     
    	unsigned int wCRCin = 0xFFFFFFFF;
    	unsigned int wCPoly = 0x04C11DB7;
     
    	InvertUint32(&wCPoly,&wCPoly);
    	while (datalen--) 	
    	{
    		wCRCin ^= *(data++);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x01)
    				wCRCin = (wCRCin >> 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin >> 1;
    		}
    	}
    	return (wCRCin ^ 0xFFFFFFFF) ;
    }
    #endif
    /****************************Info********************************************** 
     * Name:    CRC-32/MPEG-2  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 
     * Width:	32 
     * Poly:    0x4C11DB7 
     * Init:    0xFFFFFFF 
     * Refin:   False 
     * Refout:  False 
     * Xorout:  0x0000000 
     * Note: 
     *****************************************************************************/ 
    unsigned int CRC32_MPEG(unsigned char *data, unsigned int datalen)
    {
     
    	unsigned int wCRCin = 0xFFFFFFFF;
    	unsigned int wCPoly = 0x04C11DB7;
    	unsigned int wChar = 0;
    	while (datalen--) 	
    	{
    		wChar = *(data++);
    		wCRCin ^= (wChar << 24);
    		for(int i = 0;i < 8;i++)
    		{
    			if(wCRCin & 0x80000000)
    				wCRCin = (wCRCin << 1) ^ wCPoly;
    			else
    				wCRCin = wCRCin << 1;
    		}
    	}
    	return (wCRCin) ;
    }
    

    三、结束语

    在这里先感谢一下原文博主的分享,然后感谢大家能够看到这里(大部分人应该拷贝完代码就走人了),如果你觉得这篇博客能够帮到你,可以点赞收藏,后续博主也会继续发布更多实用的博客,感兴趣的同学可以关注一下,谢谢!!!

    展开全文
  • CRC校验码的理解+CRC校验码算法代码

    万次阅读 2015-11-26 20:54:48
    CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一...CRC校验码计算过程: 1,先约定一个校验码。
  • 错误检测的方法错误校验(CRC)域占用两个字节,包含了一个16位的二进制值。CRC值由传输设备计算出来,然后附加到数据帧上,接收设备在接收数据时重新计算CRC值,然后与接收到的CRC域中的值进行比较,如果这两个值不...
  • Modbus总线CRC16效验算法C语言,下面列出两种计算方法,两种方法都是可行,至于其原理在这里就不介绍了,网上可以搜索到很多。 方法一: void InvertUint8... } 计算得到的CRC要进行高低字节交换才是正确的校验位。
  • 一次项目中使用,计算其他位数校验码要修改一下代码,关键是理解
  • CRC校验码计算器 CRC校验码计算器(包含8位16位32位)
  • [导读]什么是CRC校验?CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。奇偶校验虽然简单,但是漏检率太高,而CRC则要低...
  • CRC24代码的c++程序。简单的crc24 使用c++编程的算法实现
  • CRC检验码计算——C语言(CRC8/16/32)

    千次阅读 多人点赞 2019-12-12 13:11:36
    1、循环冗余检测(Cyclic Redundancy Check,CRCCRC编码也被称为多项式编码(polynomial code),因为该编码能够将要发送的比特串看作是系数为 0 和 1 的一个多项式。对比特串操作被解释为多项式算术。 2、CRC...
  • DLT645协议解析器及modbus CRC和DLT CS校验码计算,支持两种输入格式,带空格和不带空格。默认需要安装微软VS2012发布包。 比如输入FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16,解析出结果如下: [11-05 08:...
  • 由于项目需要,解决一个流媒体文件的crc32校验码。网上查了很多的资料,发现了此校验码和生成多项式以及算法本身都有关系。对于不同类型的文件所使用的多项式以及...下面分类比较两种不同用途的crc32校验码计算方法。
  • 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 ...
  • CRC在线计算: Sunshine’s Homepage - Online CRC Calculator Javascript http://www.sunshine2k.de/coding/javascript/crc/crc_js.html crcmod.predefined – CRC calculation using predefined algorithms — ...
  • 软件版本博图15. 本程序适用于一维数组长度不超过1000字节 CrcErr=16#0,CrcValue正常,CrcErr=16#8000,数组长度超过1000字节
  • 在上一篇介绍了 CRC 校验码的原理,如何计算 CRC 校验码,这篇介绍如何利用 Verilog 实现CRC 校验码的生成。 什么是 CRC 校验码CRC 生成 Verilog 实现 CRC 校验分为发送方和接收方,根据项目的要求,对...
  • Modbus通信协议中CRC校验的快速C语言算法
  • Modbus-RTU通讯协议中CRC校验码计算步骤及算法代码

    万次阅读 多人点赞 2018-09-17 19:01:35
    CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算CRC计算方法是: 1、 预置1个16位的寄存器为十六进制FFFF(全1),此寄存器为CRC寄存器 2、 把第一个8位二进制数据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,687
精华内容 5,074
关键字:

crc校验码计算代码