CRC校验原理

article/2025/9/27 14:31:11

线性分组码中有一种重要的码称为循环码(Cyclic code),这种码编码和解码都不太复杂,而且检(纠)错能力较强。循环码除了具有线性分组码的一般性质外,还具有循环性。循环性是指任一码组循环一位以后(即将最右端的一个码元移至左端,或反之)以后,仍然为该码中的一个码组

什么是CRC校验?

CRC即循环冗余校验码:

  • 是数据通信领域中最常用的一种查错校验码;
  • 其特征是信息字段校验字段的长度可以任意选定。

循环冗余检查(CRC, Cyclic Redundancy Check)是一种数据传输检错功能,对数据进行多项式计算(利用多项式,对数据进行模2除法),并将得到的结果附在帧的后面传输,接收设备接收后也执行类似的算法(依旧利用同一个多项式,对接收的数据进行模2除法,但是这里要求没有余数才算是正确传输),以保证数据传输的正确性和完整性。CRC利用除法及余数的原理,实现错误侦测的功能,具有原理清晰、实现简单等优点。

相比于奇偶校验(PCC)只能校验一位错误,循环冗余校验码的检错能力要更强,能够检出多位错误。

CRC校验原理

      其根本思想就是先在要发送的帧后面附加一个数(即用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错

【百科】

循环冗余校验算法将是否除尽,作为数据信息的校验规则。对于能被多项式除尽的数据而言,其数据代码的误码率就较低;对于那些不能被多项式除尽的数据,需要对数据出错的地方进行分析,并将产生的余数进行减去。,如果让被校验数据减去余数,势必能为生成多项式所除尽,但网络通信中减法操作存在复杂的数学计算,无法使用拼装的方式进行数据编码。

基于此种情况,网络通信中引入模2运算的计算方式,模2运算包括:模2加、模2减、模2乘、模2除等四种二进制运算。模2运算不考虑进位和借位,即模2加法是不带进位的二进制加法运算,模2减法是不带借位的二进制减法运算。两个序列模二相加,即两个序列中对应位,相加不进位,相同为0不同为1。在两个二进制位相运算时,这两个位的值能确定最终的运算结果,而不受前一次运算的影响,因此模2运算的加减乘除属于异或运算。

 

模2除法:模2除法与算术除法类似,但每一位除的结果不影响其它位,即不向上一位借位,所以实际上就是异或。在循环冗余校验码(CRC)的计算中有应用到模2除法。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。

模2除法/乘法:

 

 

CRC校验步骤

CRC校验中有两个关键点:

(1)预先确定一个发送送端和接收端都用来作为除数的二进制比特串(或多项式G(x)),可以随机选择,也可以使用国际标准,但是最高位和最低位必须为1即生成多项式G(x)要求次数大于0,并且要求0次幂的系数为1。;

       G(x)为发送端和接收端预先约好的生成多项式。G(x)的选取对校验效果起着关键的作用,使用较多的生成多项式G(x)有CRC-16、CRC-CCITT、CRC-32等;

CRC16的生成多项式为:G(x)= X16+X10+X2+1

CRC32的生成多项式为:G(x)= X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

 

(2)把原始帧(假设为k位, 对应信息多项式)与上面计算出的除数(二进制比特串或生成多项式 G(x),假设为m位)进行模2除法运算,余数作为CRC校验码

        CRC校验码计算示例:现假设选择的CRC生成多项式为G(X) = X4 + X3 + 1,要求出二进制序列10110011的CRC校验码。

设要发送的数据码有k位,则该数据码对应的多项式F(x)有k项,k的每一位取值只能为0或1,即F(x)中每项X^n的系数只能是0或1。

R(x)为生成的 r 阶冗余码多项式,R(x)的项数比G(x)要少一项。R(x)的计算方法为:以F(x)作为被除数,先将F(x)乘x′即左移r位,再以G(x)作为除数作模2运算。

EX:选定CRC校验的生成多项式G(x)=x^4+x^3+1,待传输二进制序列1011 0011,求出其发送端的CRC校验码以及接收端的校验过程。

答:下面是具体的计算过程:

发送端:

① 将选定的多项式转化为二进制序列:由G(X) = X4 + X3 + 1可知二进制一种有五位,第4位、第三位和第零位分别为1,则序列为11001

② 多项式的位数位5,则在数据帧的后面加上5-1位0,数据帧变为101100110000,然后使用模2除法除以除数11001,得到余数0100即为CRC校验码。

③ 将计算出来的CRC校验码0100添加在原始帧的后面,真正的数据帧为10110011 0100,再把这个数据帧发送到接收端。

④ 接收端收到数据帧10110011 0100后,依3旧 用上预先选定的除数11001,用模2除法除去,验证余数是否为0,如果为0,则说明数据帧没有出错。


发送端:

接收端:


Verilog设计

分析:CRC码由发送端计算,放置于发送信息报文的尾部。接收信息的设备再重新计算接收到信息报文的CRC,比较计算得到的CRC是否与接收到的相符,如果两者不相符,则表明出错。
校验码的计算多项式为(X16 + X15 + X2 + 1,1 1000 0000 0000 0101)。具体CRC16码的计算方法是:
        1.预置1个16位的寄存器为十六进制FFFF(即全为1);称此寄存器为CRC寄存器;
        2.把第一个8位二进制数据 (既通讯信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器;
        3.把CRC寄存器的内容右移一 位(朝低位)用0填补最高位,并检查右移后的移出位;
        4.如果移出位为0:重复第3步(再次右移一位);
             如果移出位为1:CRC寄存器与多项式A001(1010 0000 0000 0001)进行异或;(Modbus)
        5.重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;
        6.重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
        7.将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
        8.最后得到的CRC寄存器内容即为:CRC码。

 

下面举例说明CRC校验码的求法:(此例子摘自百度百科:CRC校验码)


信息字段代码为: 1011001;对应m(x)=x6+x4+x3+1
假设生成多项式为:g(x)=x4+x3+1;则对应g(x)的代码为: 11001
m(x)=x10+x8+x7+x4 对应的代码记为:10110010000;
采用多项式除法: 得余数为: 1010 (即CRC校验字段为:1010)
发送方:发出的传输字段为: 1 0 1 1 0 0 1 1010
给出余数(1010)的计算步骤:
除法没有数学上的含义,而是采用计算机的模二除法,即,除数和被除数做异或运算。进行异或运算时除数和被除数最高位对齐,按位异或。
10110010000
^

11001
--------------------------
01111010000
1111010000
^11001
-------------------------
0011110000
11110000
^11001
--------------------------
00111000
111000
^11001
-------------------
001010
则四位CRC校验码就为:1010。
 

 

补充:

CRC16常见的标准有以下几种,被用在各个规范中,其算法原理基本一致,就是在数据的输入和输出有所差异,下边把这些标准的差异列出,并给出C语言的算法实现。

CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_CCITT_FALSE:多项式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,结果与0x0000异或

CRC16_XMODEM:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,结果与0x0000异或

CRC16_X25:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_MODBUS:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或

CRC16_IBM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或

CRC16_MAXIM:多项式x16+x15+x2+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

CRC16_USB:多项式x16+x15+x2+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或

 

————————————————
原文链接:https://blog.csdn.net/li200503028/article/details/26591243

下面给出CRC校验码的verilog实现方式:
本例中实现了求得8bit信息序列的CRC校验码,生成多项式取g(x)=X^16+X^12+X^5+1,对应的生成序列为1_0001_0000_0010_0001,输入的8bit序列data左移16位后得到stemp={data,16‘b0000_0000_0000_0000} ,每次异步复位信号rst_n复位时将crc的值清零并把线型变量stemp的值打入寄存器temp中,然后通过时序电路将temp与生成多项式对应的序列进行多次按位异或,最终得到一个小于生成序列的temp后,temp[15:0]的值即为CRC校验序列,并把它赋给输出crc。
 下面是code:


//信息码      : 8bit
//生成多项式  :1_0001_0000_0010_0001
//附加位      :0000 0000 0000 0000
//传输的码    : data+0000 0000 0000 0000 =24位
module crc(clk  ,data ,rst_n ,crc  
);
input      [7:0]   data   ;
input              clk    ;
input              rst_n  ;
output reg [15:0]  crc=0  ;
wire       [23:0]  stemp  ; 
reg        [23:0]  temp=0 ;
parameter polynomial=17'b1_0001_0000_0010_0001;
assign stemp={data,16'b0000000000000000};always @ (posedge clk or negedge rst_n)begin if(!rst_n)begincrc  <= 0     ;temp <= stemp ; endelse beginif(temp[23])      temp[23:7]<=temp[23:7]^polynomial;else if(temp[22]) temp[22:6]<=temp[22:6]^polynomial;else if(temp[21]) temp[21:5]<=temp[21:5]^polynomial;else if(temp[20]) temp[20:4]<=temp[20:4]^polynomial;else if(temp[19]) temp[19:3]<=temp[19:3]^polynomial;else if(temp[18]) temp[18:2]<=temp[18:2]^polynomial;else if(temp[17]) temp[17:1]<=temp[17:1]^polynomial;else if(temp[16]) temp[16:0]<=temp[16:0]^polynomial;else   crc<=temp[15:0];    endend  
endmodule


testbench:

module testbench;
// Inputs
reg clk;
reg [7:0] data;
reg rst_n;// Outputs
wire [15:0] crc;// Instantiate the Unit Under Test (UUT)
crc uut (
.clk(clk), 
.data(data), 
.rst_n(rst_n), 
.crc(crc)
);
initial begin
// Initialize Inputsclk=0;
data=0;
rst_n=0;
#100data =8'b10110110;
rst_n = 1;// Wait 100 ns for global reset to finish
#50;
rst_n =0;
#50
rst_n =1;#1000data =8'b01001100;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000data =8'b10110011;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000data =8'b10010110;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
#1000data =8'b10100101;
rst_n = 1;
#50;
rst_n =0;
#50
rst_n =1;
// Add stimulus here
endalways #10 clk=~clk;
endmodule


下面是仿真结果:
testbench中加了5组输入的data值,仿真结果已通过软件《CRC计算器》验证,全部正确。

 

 

 

 

 


http://chatgpt.dhexx.cn/article/K8gZYu6A.shtml

相关文章

CRC码计算及校验原理计算

如何根据多项式计算 循环CRC码 5.3.2 循环冗余校验检错方案 奇偶校验码&#xff08;PCC&#xff09;只能校验一位错误&#xff0c;本节所要介绍的循环冗余校验码&#xff08;CRC&#xff09;的检错能力更强&#xff0c;可以检出多位错误。 1. CRC校验原理 CRC校验原理看…

CRC码计算及校验原理的最通俗诠释

在上一篇发布了我的最新著作《深入理解计算机网络》一书的原始目录&#xff08;http://blog.csdn.net/lycb_gz/article/details/8199839&#xff09;&#xff0c;得到了许多读者朋友的高度关注和肯定&#xff0c;本篇接着发一篇关于CRC码校验原理和CRC码计算方面的通俗诠释的试…

最好懂的CRC校验规则讲解

文章目录 前言何为校验如何生成CRC校验码按字节位反转确定左移多少位生成多项式的数值式模二除法其它说明 前言 CRC校验的原理非常复杂&#xff0c;但是用起来却很简单&#xff0c;甚至别人写好了函数&#xff0c;直接拿来调用即可&#xff0c;但是我们还是需要了解一点这个校…

CRC校验原理及代码

参考&#xff1a;CRC校验原理及步骤https://blog.csdn.net/d_leo/article/details/73572373 什么是CRC校验&#xff1f; CRC即循环冗余校验码&#xff1a;是数据通信领域中最常用的一种查错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查&am…

CRC 校验计算

一、简介 CRC即循环冗余校验码&#xff08;Cyclic Redundancy Check&#xff09;&#xff1a;是数据通信领域中最常用的一种查错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。 其根本思想就是先在要发送的帧后面附加校验码&#xff0c;再发送给接收端。…

如何进行CRC校验

为了保证数据传输的可靠性&#xff0c;计算机网络传输数据时&#xff0c;必须采用差错检验措施&#xff0c;数据链路层广泛应用了循环冗余检验CRC&#xff08;Cyclic Redundancy Check&#xff09;的检错技术。 基本原理&#xff1a; CRC检验原理实际上就是在一个p位二进制数…

CRC校验(个人小结)

前言 之前曾经在通信原理课程学习过、也在项目中使用软件模拟过CRC校验。但是仍然有许多困惑的地方&#xff0c;在网上找的资料也是零零散散&#xff0c;于是自己根据课程学习、项目实践以及网上的资料&#xff0c;做一个小结。不当之处请在评论区指出。推荐一个CRC在线校验工…

CRC码校验纠错原理

在接收端收到了CRC码后用生成多项式为G(x)去做模2除&#xff0c;若得到余数为0,则码字无误。若如果有一位出错&#xff0c;则余数不为0&#xff0c;而且不同位出错&#xff0c;其余数也不同。可以证明&#xff0c;余数与出错位的对应关系只与码制及生成多项式有关&#xff0c;而…

CRC校验详解(附代码示例)

目录 1.CRC校验原理 2.生成多项式 3.以CRC-16校验为例讲解编程实现 3.3.1 完全按照CRC原理实现校验 3.3.2 工程中常用CRC校验过程 3.3.3 改进的CRC校验过程 4.以CRC-8校验为例讲解查表法 5.以CRC-16校验为例讲解查表法 5.1.生成表格 5.2.查表法实现 6.代码链接 CRC校…

详述CRC校验码(附代码)

关注星标公众号&#xff0c;不错过精彩内容 来源 | 一口Linux CRC校验应用比较广泛&#xff0c;通常在通信领域用的比较多&#xff0c;即便是自定义通信协议&#xff0c;也可以添加CRC校验码&#xff0c;使其通信更加可靠。 今天就来进一步描述CRC校验码。 一、CRC概念 1. 什么…

【科普】CRC校验(一)什么是CRC校验?

目录 CRC&#xff08;循环冗余校验&#xff09; CRC 校验码的生成 CRC 的发送方与接收方 发送方 接收方 除法异或运算示意图 CRC&#xff08;循环冗余校验&#xff09; CRC&#xff08;Cyclic Redundancy Check&#xff09;循环冗余检验&#xff0c;是一种用于检测数字数…

CRC校验原理及其C语言实现

文章目录 目录前言CRC算法简介CRC参数模型CRC计算CRC校验CRC计算的C语言实现CRC计算工具总结参考资料 目录 前言CRC算法简介CRC计算CRC校验CRC计算的C语言实现CRC计算工具总结 前言 最近的工作中&#xff0c;要实现对通信数据的CRC计算&#xff0c;所以花了两天的时间好好研…

Oracle Toad 导数,麒峰

标签&#xff1a; 补丁下载 x86 ia64 操作系统 迅雷下载 oracle it (2011-05-26 10:28) 标签&#xff1a; 授予的权限 主键约束 对象 角色管理 数据字典 oracle it 系统权限&#xff1a; create table :create any table: drop table: create procedure: execute anycedure: cr…

最优捕捞

一、问题重述 为了保护人类赖以生存的自然环境&#xff0c;可再生资源&#xff08;如渔业、林业资源&#xff09;的开发必须适度。一种合理、简化的策略是&#xff0c;在实现可持续收获的前提下&#xff0c;追求最大产量或最佳效益。 假设这种鱼分4个年龄组&#xff1a;称1龄…

短期趋势自用经传捕捞季节 通达信指标公式副图 源码 贴图

指标公式描述 短期趋势自用经传捕捞季节 通达信指标公式副图 源码 贴图 图示: 指标源码&#xff1a; WY1001:(2*CLOSEHIGHLOW)/4; WY1002:EMA(WY1001,2); WY1003:EMA(WY1002,2); WY1004:EMA(WY1003,2); XYS0:(WY1004-REF(WY1004,1))/REF(WY1004,1)*100; STICKLINE(XYS0>0,X…

股票指标使用 - 捕捞季节

股票指标里面我觉得这个指标是最实用的了&#xff0c;XX软件里面流行起来的。作为IT男&#xff0c;任何带有逻辑运算的都会让我感兴趣。 接下来就用简单易懂的文字介绍下这个指标怎么看(百度上搜到的都说了那么深奥) 如图&#xff1a; 优势&#xff1a;相对MACD指标来说&…

捕捞季节 通达信副图指标公式 源码

捕捞季节是一个趋势型指标&#xff0c;主要用于&#xff08;超&#xff09;短线的股价运行趋势状态监控。捕捞季节通达信指标公式主要用途是用来做短期买卖点操作的指标公式&#xff0c;适合那些做短期买卖的股民。 【指标用法】 紫色线上穿黄色线为金叉买入信号&#xff0c;…

通达信指标:捕捞季节

通达信【捕捞季节】指标 WY1001:(2CLOSEHIGHLOW)/3; WY1002:EMA(WY1001,3); WY1003:EMA(WY1002,3); WY1004:EMA(WY1003,3); XYS0:(WY1004-REF(WY1004,1))/REF(WY1004,1)100; STICKLINE(XYS0>0,XYS0,0,2,0),COLORRED; STICKLINE(XYS0<0,XYS0,0,2,0),COLORGREEN; PJGJ:AMO…

x86服务器与arm服务器

服务器是提供计算服务的设备&#xff0c;服务器的构成包括处理器、硬盘、内存、系统总线等&#xff0c;和通用的计算机架构类似&#xff0c;但是由于需要提供高可靠的服务&#xff0c;因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。在网络环境下…

服务器 raid配置

这里写目录标题 首先启动Server在启动界面&#xff0c;按键盘ESC或Del键进入BIOS。设置启动模式为“LEGACY”传统模式&#xff0c;F4 保存并退出重启服务器。ctrlA进入raid配置 首先启动Server在启动界面&#xff0c;按键盘ESC或Del键进入BIOS。 设置启动模式为“LEGACY”传统模…