数据校验--CRC校验

2024-05-01 13:48
文章标签 数据 校验 crc

本文主要是介绍数据校验--CRC校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

工作原理:
    CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。
    循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
    循环冗余校验码(CRC)的基本原理是:在K位信息码后再拼接R位的校验码,整个编码长度为N位,因此,这种编码也叫(N,K)码。
    对于一个给定的(N,K)码,可以证明存在一个最高次幂为N-K=R的多项式G(x)。根据G(x)可以生成K位信息的校验码,而G(x)叫做这个CRC码的生成多项式。 
    校验码的具体生成过程为:假设要发送的信息用多项式C(X)表示,将C(x)左移R位(可表示成C(x)*2^R),这样C(x)的右边就会空出R位,这就是校验码的位置。
    用 C(x)*2^R 除以生成多项式G(x)得到的余数就是校验码。
    任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’取值的多项式一一对应。例如:代码1010111对应的多项式为x6+x4+x2+x+1,而多项式为x5+x3+x2+x+1对应的代码101111。
基本概念:
    对应关系:
        多项式和二进制数有直接对应关系:X的最高幂次对应二进制数的最高位,以下各位对应多项式的各幂次,有此幂次项对应1,无此幂次项对应0。
        可以看出:X的最高幂次为R,转换成对应的二进制数有R+1位。
        多项式包括生成多项式G(X)和信息多项式C(X)。
        如生成多项式为G(X)=X4+X3+X+1, 可转换为二进制数码11011
        而发送信息位 101111,可转换为数据多项式为C(X)=X5+X3+X2+X+1。
    生成多项式:
        是接受方和发送方的一个约定,也就是一个二进制数,在整个传输过程中,这个数始终保持不变。
        在发送方,利用生成多项式对信息多项式做模2除生成校验码。在接收方利用生成多项式对收到的编码多项式做模2除检测和确定错误位置。
        应满足以下条件:
            A、生成多项式的最高位和最低位必须为1。
            B、当被传送信息(CRC码)任何一位发生错误时,被生成多项式做除后应该使余数不为0。
            C、不同位发生错误时,应该使余数不同。
            D、对余数继续做除,应使余数循环。
    校验码位数:
        CRC校验码位数 = 生成多项式位数 - 1。注意有些生成多项式的简记式中将生成多项式的最高位1省略了。
    生成步骤:
        1、将X的最高次幂为R的生成多项式G(X)转换成对应的R+1位二进制数。
        2、将信息码左移R位,相当于对应的信息多项式C(X)*2^R。
        3、用生成多项式(二进制数)对信息码做除,得到R位的余数(注意:这里的二进制做除法得到的余数其实是模2除法得到的余数,并不等于其对应十进制数做除法得到的余数。)。
        4、将余数拼到信息码左移后空出的位置,得到完整的CRC码。
        例:假设使用的生成多项式是G(X)=X3+X+1。4位的原始报文为1010,求编码后的报文。
        1、将生成多项式G(X)=X3+X+1转换成对应的二进制除数1011。
        2、此题生成多项式有4位(R+1)(注意:4位的生成多项式计算所得的校验码为3位,R为校验码位数),要把原始报文C(X)左移3(R)位变成1010 000
        3、用生成多项式对应的二进制数对左移3位后的原始报文进行模2除(高位对齐),相当于按位异或:
        1010000
        1011
        ————————————
        0001000
        1000
        1011
        ————————————
        0011
        得到的余位011,所以最终编码为:1010 011
生成方法:
    借助于模2除法则,其余数为校验字段。
    例如:信息字段代码为: 1011001;对应m(x)=x6+x4+x3+1
    假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001
    x^4*m(x)=x10+x8+x7+x4 对应的代码记为:10110010000(相当于1011001<<4);
    采用模2除法则: 得余数为: 1010(即校验字段为:1010)
    发送方:发出的传输字段为: 10110011010 信息字段+校验字段
    接收方:使用相同的生成码进行校验:接收到的字段/生成码(二进制除法)如果能够除尽,则正确,
    给出余数(1010)的计算步骤:
    除法没有数学上的含义,而是采用计算机的模二除法,即除数和被除数做异或运算。进行异或运算时除数和被除数最高位对齐,按位异或。
    10110010000
    11001
    ————————————
    01111010000
    1111010000
    11001
    ————————————
    0011110000
    11110000
    11001
    ————————————
    00111000
    111000
    11001
    ————————————
    001010
    1010
    则四位CRC校验码就为:1010。
    利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,
    后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
位宽:
    有一点要特别注意:生成多项式经常会说到多项式的位宽(Width,简记为W),这个位宽不是多项式对应的二进制数的位数,而是二进制位数减1。比如CRC8中用到的位宽为8的生成多项式,
    其实对应得二进制数有九位:100110001。另外一点,多项式表示和二进制表示都很繁琐,交流起来不方便,因此,多用16进制简写法来表示,因为生成多项式的最高位肯定为1,
    最高位的位置由位宽可知,故在简记式中,将最高的1统一去掉了,如CRC32的生成多项式简记为04C11DB7实际上表示的是104C11DB7。


CRC算法的编程实现:
    STM32硬件实现:
        1. 开启CRC单元的时钟。RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE)
        2. 复位CRC模块(设置CRC_CR=0x01),这个操作把CRC余数初始化为0xFFFFFFFF  CRC_ResetDR(void) 
        3. 把要计算的数据按逐个地写入CRC_DR寄存器  
            uint32_t CRC_CalcCRC(uint32_t Data); 将一个数据写入CRC_DR寄存器,返回值为计算结果。
            uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength);计算一个数组的CRC 值。
        4. 写完所有的数据字后,从CRC_DR寄存器读出计算的结果
        例程:
        #include "stm32f10x.h"
        #define BUFFER_SIZE    114
        static const uint32_t DataBuffer[BUFFER_SIZE] =
          {
            0x00001021, 0x20423063, 0x408450a5, 0x60c670e7, 0x9129a14a, 0xb16bc18c,
            0xd1ade1ce, 0xf1ef1231, 0x32732252, 0x52b54294, 0x72f762d6, 0x93398318,
            0xa35ad3bd, 0xc39cf3ff, 0xe3de2462, 0x34430420, 0x64e674c7, 0x44a45485,
            0xa56ab54b, 0x85289509, 0xf5cfc5ac, 0xd58d3653, 0x26721611, 0x063076d7,
            0x569546b4, 0xb75ba77a, 0x97198738, 0xf7dfe7fe, 0xc7bc48c4, 0x58e56886,
            0x78a70840, 0x18612802, 0xc9ccd9ed, 0xe98ef9af, 0x89489969, 0xa90ab92b,
            0x4ad47ab7, 0x6a961a71, 0x0a503a33, 0x2a12dbfd, 0xfbbfeb9e, 0x9b798b58,
            0xbb3bab1a, 0x6ca67c87, 0x5cc52c22, 0x3c030c60, 0x1c41edae, 0xfd8fcdec,
            0xad2abd0b, 0x8d689d49, 0x7e976eb6, 0x5ed54ef4, 0x2e321e51, 0x0e70ff9f,
            0xefbedfdd, 0xcffcbf1b, 0x9f598f78, 0x918881a9, 0xb1caa1eb, 0xd10cc12d,
            0xe16f1080, 0x00a130c2, 0x20e35004, 0x40257046, 0x83b99398, 0xa3fbb3da,
            0xc33dd31c, 0xe37ff35e, 0x129022f3, 0x32d24235, 0x52146277, 0x7256b5ea,
            0x95a88589, 0xf56ee54f, 0xd52cc50d, 0x34e224c3, 0x04817466, 0x64475424,
            0x4405a7db, 0xb7fa8799, 0xe75ff77e, 0xc71dd73c, 0x26d336f2, 0x069116b0,
            0x76764615, 0x5634d94c, 0xc96df90e, 0xe92f99c8, 0xb98aa9ab, 0x58444865,
            0x78066827, 0x18c008e1, 0x28a3cb7d, 0xdb5ceb3f, 0xfb1e8bf9, 0x9bd8abbb,
            0x4a755a54, 0x6a377a16, 0x0af11ad0, 0x2ab33a92, 0xed0fdd6c, 0xcd4dbdaa,
            0xad8b9de8, 0x8dc97c26, 0x5c644c45, 0x3ca22c83, 0x1ce00cc1, 0xef1fff3e,
            0xdf7caf9b, 0xbfba8fd9, 0x9ff86e17, 0x7e364e55, 0x2e933eb2, 0x0ed11ef0
          };
        __IO uint32_t CRCValue = 0;
        /**
          * @brief  Main program.
          * @param  None
          * @retval None
          */
        int main(void)
        {
          /*!< At this stage the microcontroller clock setting is already configured, 
               this is done through SystemInit() function which is called from startup
               file (startup_stm32f10x_xx.s) before to branch to application main.
               To reconfigure the default setting of SystemInit() function, refer to
               system_stm32f10x.c file
             */       
          /* Enable CRC clock */
          RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
          /* Compute the CRC of "DataBuffer" */
          CRCValue = CRC_CalcBlockCRC((uint32_t *)DataBuffer, BUFFER_SIZE);
          while (1)
          {
          }
        }


    软件编程(CRC32):
    #define poly 0xEDB88320
    int crc32(char *addr, int num, int crc)
    {
        int i;

        for (; num>0; num--)              /* Step through bytes in memory */
        {
          crc = crc ^ *addr++;            /* Fetch byte from memory, XOR into CRC */
          for (i=0; i<8; i++)             /* Prepare to rotate 8 bits */
          {
            if (crc & 1)                  /* b0 is set... */
              crc = (crc >> 1) ^ poly;    /* rotate and XOR with ZIP polynomic */
            else                          /* b0 is clear... */
              crc >>= 1;                  /* just rotate */
            }                             /* Loop for 8 bits */
        }                                 /* Loop until num=0 */
          return(crc);                    /* Return updated CRC */
    }

这篇关于数据校验--CRC校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/951857

相关文章

【服务器运维】MySQL数据存储至数据盘

查看磁盘及分区 [root@MySQL tmp]# fdisk -lDisk /dev/sda: 21.5 GB, 21474836480 bytes255 heads, 63 sectors/track, 2610 cylindersUnits = cylinders of 16065 * 512 = 8225280 bytesSector size (logical/physical)

SQL Server中,查询数据库中有多少个表,以及数据库其余类型数据统计查询

sqlserver查询数据库中有多少个表 sql server 数表:select count(1) from sysobjects where xtype='U'数视图:select count(1) from sysobjects where xtype='V'数存储过程select count(1) from sysobjects where xtype='P' SE

数据时代的数字企业

1.写在前面 讨论数据治理在数字企业中的影响和必要性,并介绍数据治理的核心内容和实践方法。作者强调了数据质量、数据安全、数据隐私和数据合规等方面是数据治理的核心内容,并介绍了具体的实践措施和案例分析。企业需要重视这些方面以实现数字化转型和业务增长。 数字化转型行业小伙伴可以加入我的星球,初衷成为各位数字化转型参考库,星球内容每周更新 个人工作经验资料全部放在这里,包含数据治理、数据要

如何在Java中处理JSON数据?

如何在Java中处理JSON数据? 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在Java中如何处理JSON数据。JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,在现代应用程序中被广泛使用。Java通过多种库和API提供了处理JSON的能力,我们将深入了解其用法和最佳

两个基因相关性CPTAC蛋白组数据

目录 蛋白数据下载 ①蛋白数据下载 1,TCGA-选择泛癌数据  2,TCGA-TCPA 3,CPTAC(非TCGA) ②蛋白相关性分析 1,数据整理 2,蛋白相关性分析 PCAS在线分析 蛋白数据下载 CPTAC蛋白组学数据库介绍及数据下载分析 – 王进的个人网站 (jingege.wang) ①蛋白数据下载 可以下载泛癌蛋白数据:UCSC Xena (xena

中国341城市生态系统服务价值数据集(2000-2020年)

生态系统服务反映了人类直接或者间接从自然生态系统中获得的各种惠益,对支撑和维持人类生存和福祉起着重要基础作用。目前针对全国城市尺度的生态系统服务价值的长期评估还相对较少。我们在Xie等(2017)的静态生态系统服务当量因子表基础上,选取净初级生产力,降水量,生物迁移阻力,土壤侵蚀度和道路密度五个变量,对生态系统供给服务、调节服务、支持服务和文化服务共4大类和11小类的当量因子进行了时空调整,计算了

【计算机网络篇】数据链路层(12)交换机式以太网___以太网交换机

文章目录 🍔交换式以太网🛸以太网交换机 🍔交换式以太网 仅使用交换机(不使用集线器)的以太网就是交换式以太网 🛸以太网交换机 以太网交换机本质上就是一个多接口的网桥: 交换机的每个接口考研连接计算机,也可以理解集线器或另一个交换机 当交换机的接口与计算机或交换机连接时,可以工作在全双工方式,并能在自身内部同时连通多对接口,使每一对相互通信的计算机都能像

使用Jsoup抓取数据

问题 最近公司的市场部分布了一个问题,到一个网站截取一下医院的数据。刚好我也被安排做。后来,我发现为何不用脚本去抓取呢? 抓取的数据如下: Jsoup的使用实战代码 结构 Created with Raphaël 2.1.0 开始 创建线程池 jsoup读取网页 解析Element 写入sqlite 结束

Excel实用技巧——二级下拉菜单、数据验证

EXCEL系列文章目录   Excel系列文章是本人亲身经历职场之后萌发的想法,为什么Excel覆盖如此之广,几乎每个公司、学校、家庭都在使用,但是它深藏的宝藏功能却很少被人使用,PQ、BI这些功能同样适用于数据分析;并且在一些需要简单及时的数据分析项目前,Excel是完胜python、R、SPSS这些科学专业的软件的。因此决心开启Excel篇章。 数据分析为什么要学Excel Excel图表

OSG学习:LOD、数据分页、动态调度

LOD(level of detail):是指根据物体模型的结点在显示环境中所处的位置和重要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。在OSG的场景结点组织结构中,专门提供了场景结点osg::LOD来表达不同的细节层次模型。其中,osg::LOD结点作为父节点,每个子节点作为一个细节层次,设置不同的视域,在不同的视域下显示相应的子节点。 数据分页:在城市