当前位置:首页 » 操作系统 » crc检验算法

crc检验算法

发布时间: 2023-05-30 14:50:01

Ⅰ 关于CRC效验

为保证传输过程的正确性,需要对通信过程进行差错控制。差错控制最常用的方法是自动请求重发方式(ARQ)、向前纠错方式(FEC)和混合纠错(HEC)。在传输过程误码率比较低时,用FEC方式比较理想。在传输过程误码率较高时,采用FEC容易出现“乱纠”现象。HEC方式则是ARQ和FEC的结合。在许多数字通信中,广泛采用ARQ方式,此时的差错控制只需要检错功能。实现检错功能的差错控制方法很多,传统的有:奇偶校验、校验和检测、重复码校验、恒比码校验、行列冗余码校验等,这些方法都是增加数据的冗余量,将校验码和数据一起发送到接受端。接受端对接受到的数据进行相同校验,再将得到的校验码和接受到的校验码比较,如果二者一致则认为传输正确。但这些方法都有各自的缺点,误判的概率比较高。
循环冗余校验CRC(Cyclic Rendancy Check)是由分组线性码的分支而来,其主要应用是二元码组。编码简单且误判概率很低,在通信系统中得到了广泛的应用。下面重点介绍了CRC校验的原理及其算法实现。

CRC校验可以100%地检测出所有奇数个随机错误和长度小于等于k(k为g(x)的阶数)的突发错误。所以CRC的生成多项式的阶数越高,那么误判的概率就越小。

CRC代码的一些基本概念和运算:

CRC多项式:

例:

代码:1010111 对应的多项式为:X6+X4+X2+X+1

多项式X5+X3+X2+X1+1对应的代码为101111

CRC生成多项式:

首位和最后一位必须是1。CRC生成多项式是给定的,在传输过程中不变,即发送和接收端生成码相同。

一些常用的校验码为:

CRC8=X8+X5+X4+1

CRC-CCITT=X16+X12+X5+1

CRC16=X16+X15+X5+1

CRC12=X12+X11+X3+X2+1

CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+1

CRC的运算本质是异或运算(模2除法)

例:原信息码为1011001

生成码为11001

校验码计算过程

① 将信息码左移4位(生成码长-1);得到10110010000

② 异或运算

10110010000

11001

01111010000(前面的数进行异或运算,后面的直接抄下来)

11001

0011110000(和生成码异或运算的必须从1开始)

11001

00111000

11001

001010

这样得到的结果为1010,即为所需要的校验码,添加到信息码后,得到发送的代码为:

10110011010

我把上面的手算过程用c#写了一段程序,如下:

using System;

namespace mainClass
{
public class mainProgress
{
public static void Main()
{
byte[] msg={1,0,1,1,0,0,1};//信息码
byte[] gmsg=new byte[msg.Length+4];
crc c = new crc();
gmsg=c.code(msg);
Console.Write("编码后字符串为:");
for (int i = 0; i < gmsg.Length; i++)
{
Console.Write("{0}", gmsg[i].ToString());
}
Console.Write("\n");
byte[] gmsg1={ 1, 0, 1, 1, 0, 1, 1 };//接收到的代码
bool r = c.det(gmsg1);
if (r)
{
Console.WriteLine("传输正确");
}
else
{ Console.WriteLine("传输错误"); }
}
}

public class crc//CRC编码类
{
private byte[] g = { 1,1,0,0,1};//生成码
public byte[] code(byte[] msg)//编码
{
byte[] gmsg=new byte[g.Length+msg.Length-1];
msg.CopyTo(gmsg, 0);//
for (int i = 0; i < msg.Length; i++)//完成异或运算,即模2除法
{
if (gmsg[i] == 1)
{
for (int j = 0; j < g.Length; j++)
{
if (gmsg[i + j] == g[j])
gmsg[i + j] = 0;
else
gmsg[i + j] = 1;
}
}
}
msg.CopyTo(gmsg, 0);
return gmsg;
}
private bool f=true;

//接收端检测
public bool det(byte[] gmsg)
{
for (int i = 0; i < gmsg.Length - g.Length+1; i++)
{
if(gmsg[i]==0)
continue;
for (int j = 0; j < g.Length; j++)
{
if (gmsg[i + j] == g[j])
gmsg[i + j] = 0;
else
gmsg[i + j] = 1;
}
}
for (int i = 0; i < gmsg.Length; i++)
{
if (gmsg[i] == 1)
f = false;
}
return f;
}

}
}

Ⅱ modbus中如何计算CRC效验(人工计算)

在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。

CRC计算方法是:

1、 加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器。

2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。

3、 把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。

4、 如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与0XA001进行异或。

(2)crc检验算法扩展阅读:

计算步骤为:

(1).预置 16 位寄存器为十六进制 FFFF(即全为 1) ,称此寄存器为 CRC 寄存器;

(2).把第一个 8 位数据与 16 位 CRC 寄存器的低位相异或,把结果放于 CRC 寄

存器;

(3).检测相异或后的CRC寄存器的最低位,若最低位为1:CRC寄存器先右移1位,再与多项式A001H进行异或;若为0,则CRC寄存器右移1位,无需与多项式进行异或。

(4).重复步骤 3 ,直到右移 8 次,这样整个 8 位数据全部进行了处理;

(5).重复步骤 2 到步骤4,进行下一个 8 位数据的处理;

(6).最后得到的 CRC 寄存器即为 CRC 码。

Ⅲ CRC校验的算法

在代数编码理论中,将一个码组表示为一个多项式,码组中各码元当作多项式的系数。例如 1100101 表示为1·x6+1·x5+0·x4+0·x3+1·x2+0·x+1,即 x6+x5+x2+1。
设编码前的原始信息多项式为P(x),P(x)的最高幂次加1等于k;生成多项式为G(x),G(x)的最高幂次等于r;CRC多项式为R(x);编码后的带CRC的信息多项式为T(x)。
发送方编码方法:将P(x)乘以xr(即对应的二进制码序列左移r位),再除以G(x),所得余式即为R(x)。用公式表示为T(x)=xrP(x)+R(x)
接收方解码方法:将T(x)除以G(x),得到一个数,如果这个余数为0,则说明传输中无错误发生,否则说明传输有误。
举例来说,设信息编码为1100,生成多项式为1011,即P(x)=x3+x2,G(x)=x3+x+1,计算CRC的过程为
xrP(x) =x3(x3+x2) = x6+x5 G(x)= x3+x+1 即 R(x)=x。注意到G(x)最高幂次r=3,得出CRC为010。
如果用竖式除法(计算机的模二,计算过程为
1110 ------- 1011 /1100000 (1100左移3位) 1011 ---- 1110 1011 ----- 1010 1011 ----- 0010 0000 ---- 010 因此,T(x)=(x6+x5)+(x)=x6+x5+x, 即 1100000+010=1100010
如果传输无误,
T(x)= (x6+x5+x)/G(x) = , G(x)= 无余式。回头看一下上面的竖式除法,如果被除数是1100010,显然在商第三个1时,就能除尽。
上述推算过程,有助于我们理解CRC的概念。但直接编程来实现上面的算法,不仅繁琐,效率也不高。实际上在工程中不会直接这样去计算和验证CRC。
下表中列出了一些见于标准的CRC资料:
名称 生成多项式 简记式* 应用举例
CRC-4 x4+x+1 3 ITU G.704
CRC-8 x8+x5+x4+1 31 DS18B20
CRC-12 x12+x11+x3+x2+x+1 80F
CRC-16 x16+x15+x2+1 8005 IBM SDLC
CRC-ITU** x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS,ZigBee
CRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI,IEEE 1394,PPP-FCS
CRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP
* 生成多项式的最高幂次项系数是固定的1,故在简记式中,将最高的1统一去掉了,如04C11DB7实际上是104C11DB7。 ** 前称CRC-CCITT。ITU的前身是CCITT。
备注:
(1)生成多项式是标准规定的
(2)CRC校验码是基于将位串看作是系数为0或1的多项式,一个k位的数据流可以看作是关于x的从k-1阶到0阶的k-1次多项式的系数序列。采用此编码,发送方和接收方必须事先商定一个生成多项式G(x),其高位和低位必须是1。要计算m位的帧M(x)的校验和,基本思想是将校验和加在帧的末尾,使这个带校验和的帧的多项式能被G(x)除尽。当接收方收到加有校验和的帧时,用G(x)去除它,如果有余数,则CRC校验错误,只有没有余数的校验才是正确的。

Ⅳ 谁能把crc校验一步步算出来

从(1)看,你已经考虑了算法要求的初值问题,从(3)看,你已经考虑了数据的排列问题,使用的是低位先传输低位先校验的方式,那还有两个问题:

  1. 计算步骤,从你的讲述上,你是先判断最低位为1,做异或,再移位,这个步骤不符合要求。应该是先判断最低位为1,先移位,再做异或;如果最低位为0,则移位,但不做异或。具体的原理一下说不清楚,我借花献佛,推荐你搜一下一个文档:“我学习CRC32、CRC16、CRC 原理和算法的总结(与WINRAR 结果一致)”,其中“三 直接计算法”可以解决你的问题,但建议你把之前的一二都看了,我前段时间做以太正橘网的CRC32校验的时候被整的死去活来,最后发现这个文档讲得很有条理,虽然应用不同,但原理相同,感谢作者。

  2. 确定一下你最后的CRC码是否需要取反,因为很多传输用的算法,带清没如果要对CRC校验码后的0的个数敏感,是需要对其CRC码取反的,你做完1后,如果结果还不对,可以试着取反试试。最后再确定一下算法要求的CRC码值的排放顺序,这个也会影响你最终结果的表现形式。

差点被你绕进去了,你的计算是使用的检查最低位蠢纳,向右移的方式,那你的生成多项式是不是也已经相应的进行了翻转?将高低位按序反着放了?建议你还是找到你要做的这个算法的规范文本,确认一下规则。

Ⅳ 循环冗余校验(CRC)码

与海明校验码类似,CRC码也是数据通讯中常用的校验方式。
CRC 算法的基本思想是将传输的数据当做一个位数很长的数。将这个数除以另一个数。得到的余数作为校验数据附加到原数据后面。

与海明校验码数据位和校验位穿插不同,CRC码中,校验位(R位)在信息位(K位)后面

以一个慎碧高题目为例:设待校验的数据为。D8~D1 = 10101011,若采用CRC,且生成多项式为 10011,则其 CRC 码为:
这里首先要注意题目中的一个表述——“多项式”,该题目中写作“10011”,在有的题目中往往写作“x^4+x+1”
首先,在数据位后加 多项式最高幂次 个0,比如这里的多项式最高次项为x^4,那就在数据位后加四个0,变成:101010110000,作为被除数
然后,将多项式 10011 作为除数进行断除。需要注意的是,图中所框的部分,对应位只做xor运算,也就是做减法但不影响其他位

最后得到的余数:1010,即是校验位。那么宽尺整个CRC码为:10101011 1010

以上一节例题为例,假设收到的CRC码变成了10001011 1010,第10位(右边为低位)发生了错误。
现在尝试慧嫌用CRC码与多项式 10011 进行短除:

得到余数为 1010(2) = 1 8+1 2 = 10(10) ,即第10位发生错误,只需要反转第10位的值,便可获得正确的值

Ⅵ CRC16校验码如何计算

首先G(X)=X3+X+1可以得出G(x)=1011[G(x)中的1就是二进制第0位为1,X就是第一位为1,没有X^2,所以第二位为0,X^3则第三位为1。所以就是1011]

M(x)=0011M(x)*x3=0011000

M(x)*x3/G(x)的余数是101所以R(X)=101

CRC码为:M(x)*x3+R(x)=0011000+010=0011010

在计算机网络通信中

运用CRC校验时相对于其他校验方法就有一定的优势。CRC可以高比例的纠正信息传输过程中的错误,可以在极短的时间内完成数据校验码的计算,并迅速完成纠错过程,通过数据包自动重发的方式使得计算机的通信速度大幅提高,对通信效率和安全提供了保障。由于CRC算法检验的检错能力极强,且检测成本较低,因此在对于编码器和电路的检测中使用较为广泛。

以上内容参考:网络-CRC

Ⅶ 如何校验CRC值

作二进制除法。

1、亮野发送数据比特序列为1101011011(10比特)。

2、生成多项式比特序列为10011(5比特,K=4),X的指数就是代表第几位为1,而且1=X的0次方。

3、将发送数据比特序列乘以2的K(由2可知K为4),那么产生的乘积为11010110110000。

4、将乘积用生成多项式比特序列去除,按模二算法得到余数1110。

模二算法就是两数相减不产生借位,0-1=1。

步骤如如下所示:

(7)crc检验算法扩展阅读:

二进制除法的CRC校验原理。

RC校验原理看起来比较复杂,因为大多枯谨数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。

当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。

如果有余数,则表明该帧在传输过程中出现了差错。

【详细说明】“模2除法”与“算术除法”类似,但它既不向上位借位,也不比较除数和被除数的相同位数值的大小,只要以相同位数进行相除即可。模2加法运算为:1+1=0,0+1=1,0+0=0,无进位,也无借位;模2减法运算为:1-1=0,0-1=1,1-0=1,0-0=0,也无进位,无借位。

相当于二进制中的逻辑异或运算。也就是比没键基较后,两者对应位相同则结果为“0”,不同则结果为“1”。如100101除以1110,结果得到商为11,余数为1。

参考资料来源:网络--CRC校验

Ⅷ 求CRC校验计算方法

你这个是CRC16
要实现校验的话,你首先需要知道对方采用的是何种CRC公式
不同的CRC公式 得到的校验码是不一样的
在知道公式的情况下
做crc表,然后按照crc算法,计算这8个字节的整体crc
如果传输没有错误的话,最终的crc值是0
也可以计算前六个的crc,然后和最后两个字节比较,效果是相同的。

Ⅸ crc校验码计算方法是什么

已知信息位为1100,生成多项式G(x) = x3+x+1,求CRC码。

M(x) = 1100 M(x)*x3 = 1100000 G(x) = 1011

M(x)*x3 / G(x) = 1110 + 010 /1011 R(x) = 010

CRC码为: M(x)*x 3+R(x)=1100000+010 =1100010

其原理是:CRC码一般在k位信息位之后拼接r位校验位生成。编码步骤如下:

(1)将待编码的k位信息表示成多项式 M(x)。

(2)将 M(x)左移 r 位,得到 M(x)*xr 。

(3)用r+1位的生成多项式G(x)去除M(x)*xr 得到余数R(x)。

(4)将M(x)*xr 与R(x)作模2加,得到CRC码。

(9)crc检验算法扩展阅读:

CRC校验码计算详解:采用CRC进行差错检验,生成多项式为G(X)=X4+X+1,信息码字为10110,则计算出的CRC校验码是:A. 0000 B. 0100 C. 0010 D.1111

符号表示假定:多项式和多项式的系数排列均用相同的符号表示,如

G(X)= X4+X+1

G(X)=10011

已知条件如下:

原码字记做M(X),即:M(X) = 10110

生成多项式记做G(X),即:G(X) = 10011

G(X)的最高阶数记做r,此处r = 4

Ⅹ CRC校验全解

这几天一直在看CRC校验算法。CRC版本众多,网站上实现算法一大坨,可一开始根本搞不清楚那个是哪个。连续上网络,哔哩哔哩,知乎看了很多解读CRC算法的,终于有了一些眉目,打算写下来,方便日后参考。

CRC算法核心其实只有一种,即二进制除法的实现橘清,版本众多的原因主要有以下几个原因:

CRC字段的长度

多项式公式

初始值

输出是否水平翻转

输入是否水平翻转

结果异或值

我绝大多数的文章都只谈到了CRC字段的长度和多项式公式,没有涉及剩余的三项在crc算法中的应用。

CRC字段的长度 ,字段越长,对于crc算法的校验能力越强。如果我们用出错的概率来评宏旦估校验能力的话。N长度的字段,他的校验能力为1/2**N。此处的运算符号采用Python语言中的含义。

一般而言,我们取的长度主要有8位,16位和32位。当然也有一些比较奇特的,4位,5位和6位,还有7位。

多项式公式 是我们二进制多项蔽伍扰式算法中的除数。不同的算法往往取的多项式是不一样的。

初始值 ,是指CRC字段的初始值。常常是从0和全是1中选择。

输入反转。 具体的操作方法实施将输入的数据按照字节为单位进行水平反转。比如01000001,翻转结果是10000010。

输出翻转 。输出翻转的操作与输入翻转操作是一样的。只是输出翻转是将整个CRC字段进行水平翻转。

结果异或值 ,是用来和 通过上述的算法算出来的结果 进行异或的一个数据值。如果这个值是0的话,那么就相当于没有进行异或。

为什么需要这么多看起来乱七八糟的种类呢。这些算法分别针对不同的数据的检验。针对不同的数据的特性,比如说某些数据,一开始就会有大量的零,如果不采用输入翻转或者初始值的话,那么这些0就对于校验结果没有任何影响。这就如我们想要的结果有出入了,我们希望校验结果和数据是一一对应的,并且是唯一的。如果不唯一那么,校验结果也就失去了意义。因此这么多算法的出现,主要原因就是为了适应不同的数据字符串的特点。

下面就是一些例子了。

验证网站: http://www.ip33.com/crc.html

热点内容
scratch少儿编程课程 发布:2025-04-16 17:11:44 浏览:639
荣耀x10从哪里设置密码 发布:2025-04-16 17:11:43 浏览:368
java从入门到精通视频 发布:2025-04-16 17:11:43 浏览:84
php微信接口教程 发布:2025-04-16 17:07:30 浏览:310
android实现阴影 发布:2025-04-16 16:50:08 浏览:793
粉笔直播课缓存 发布:2025-04-16 16:31:21 浏览:344
机顶盒都有什么配置 发布:2025-04-16 16:24:37 浏览:213
编写手游反编译都需要学习什么 发布:2025-04-16 16:19:36 浏览:812
proteus编译文件位置 发布:2025-04-16 16:18:44 浏览:366
土压缩的本质 发布:2025-04-16 16:13:21 浏览:592