CRC查表法 计算法

合集下载

一种CRC并行计算原理及实现方法

一种CRC并行计算原理及实现方法

一种CRC并行计算原理及实现方法一种常用的CRC并行计算原理及实现方法是通过使用查表法(Table-Driven)。

CRC(循环冗余校验码)是一种常用的数据校验方法,它通过对数据进行异或运算,生成一个校验值,再将校验值附加到数据中传输,接收方根据接收到的数据和附加的校验值进行计算,如果计算的结果与已知的校验值相同,则数据传输没有错误,否则存在错误。

在CRC并行计算中,常见的被检验的数据流是按位顺序传输的。

为了加速计算过程,可以使用查表法来并行计算CRC。

查表法的基本原理是预先计算不同输入字节(8位)对应的CRC,然后利用这些预先计算的结果来进行CRC计算。

具体步骤如下:1.预先计算CRC表:可以根据CRC算法的多项式生成一张256行的CRC查表。

表中每一行对应一个8位字节,每行包含一个32位的CRC值。

这些预先计算的CRC值是通过不断对每个字节进行异或操作来计算出来的。

2.初始化CRC寄存器:将CRC寄存器初始化为全0。

3.逐字节计算:按照顺序读取待计算的数据流中的每个字节。

4.异或操作:将CRC寄存器中的高8位与当前读取的字节进行异或操作,并且将结果作为索引在CRC表中查找。

得到的结果是一个32位的CRC。

5.更新CRC寄存器:将CRC寄存器的高24位更新为从CRC表中查找到的32位CRC值。

6.继续计算:如果数据流还没有结束,重复步骤3至5,直到处理完所有字节。

7.计算结果:最后得到的CRC寄存器中的值就是校验结果,可以将其附加到数据中进行传输。

通过使用查表法的并行计算,可以加快CRC的计算速度。

因为预先计算CRC表的过程只需要进行一次,在后续的计算中只需要进行查表和异或操作,而不需要再进行CRC算法的计算。

此外,还有一些其他的CRC并行计算方法,如使用移位寄存器进行计算等。

这些方法根据具体的场景和需求选择使用。

总之,CRC并行计算的关键是预先计算CRC表并将结果存储起来,然后根据输入的数据进行查表和异或操作,通过并行计算的方式加速CRC的计算过程。

crc查表法计算实例

crc查表法计算实例

CRC(循环冗余校验)是一种常用的错误检测技术,其中查表法是一种高效计算CRC 值的方法。

下面是一个使用查表法计算CRC 的示例:```pythondef crc_lookup(data, crc_table):crc = 0xFFFF # 初始CRC 值for byte in data:crc = (crc >> 8) ^ crc_table[(crc ^ byte) & 0xFF]return crcdef calculate_crc(data):crc_table = [0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF] # CRC 查表# 将数据转换为字节列表if isinstance(data, str):data = data.encode()# 计算CRCcrc = crc_lookup(data, crc_table)return crc# 示例数据data = "Hello, World!"# 计算CRCcrc_result = calculate_crc(data)print(f"CRC Result: {hex(crc_result)}")```在上面的示例中,我们定义了两个函数:`crc_lookup` 和`calculate_crc`。

`crc_lookup` 函数用于执行CRC 查表操作,接受一个数据字节列表和CRC 查表作为参数,返回计算得到的CRC 值。

`calculate_crc` 函数用于将数据转换为字节列表,并调用`crc_lookup` 函数计算CRC 值。

在示例中,我们使用了一个16 位CRC 查表,以及一个示例数据"Hello, World!"。

C#CRC8校验

C#CRC8校验

public byte CRC(byte[] buffer) {
return CRC(buffer, 0, buffer.Length); }
public byte CRC(byte[] buffer, int off, int len) {
byte crc = 0; if (buffer == null) {
0,94,188,226,97,63,221,131,194,156,126,32,163,253,31,65, 157,195,33,127,252,162,64,30, 95,1,227,189,62,96,130,220, 35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98, 190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255, 70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7, 219,133,103,57,186,228,6,88,25,71,165,251,120,38,196,154, 101,59,217,135,4,90,184,230,167,249,27,69,198,152,122,36, 248,166,68,26,153,199,37,123,58,100,134,216,91,5,231,185, 140,210,48,110,237,179,81,15,78,16,242,172,47,113,147,205, 17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80, 175,241,19,77,206,144,114,44,109,51,209,143,12,82,176,238, 50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115, 202,148,118,40,171,245,23,73,8,86,180,234,105,55,213,139, 87,9,235,181,54,104,138,212,149,203, 41,119,244,170,72,22, 233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168, 116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53 };

crc16查表法使用实例

crc16查表法使用实例

crc16查表法使用实例当进行数据通信时,为了确保数据的完整性和准确性,常常会使用校验码来校验数据的正确性。

其中,CRC(循环冗余校验)是一种常用的校验码算法。

CRC16是CRC算法的一种,它采用16位的校验码来校验数据。

下面是一个使用CRC16查表法的实例,来解释这个过程。

在该实例中,我们将使用一个包含256个16位值的查表数组来计算CRC16校验码。

1. 初始化CRC16寄存器:首先,我们需要将CRC16寄存器初始化为一个预定的值,通常是全1(0xFFFF)。

2. 计算CRC16校验码:接下来,我们需要按照以下步骤来计算CRC16校验码:- 从要校验的数据中取出第一个字节(8位)。

- 将CRC16寄存器的高8位与该字节进行异或运算。

- 通过查表得到一个16位的值,该值即为CRC16校验码寄存器的新值。

- 将CRC16寄存器更新为上一步得到的新值。

- 重复上述步骤,直到对所有字节进行了处理。

3. 最终CRC16校验码:当所有字节都处理完毕后,CRC16寄存器中的值即为最终的CRC16校验码。

4. 校验结果:在数据通信中,发送方会将计算得到的CRC16校验码随数据一起发送给接收方。

接收方在收到数据后,同样使用CRC16查表法来计算校验码。

然后,接收方将计算得到的校验码与发送方提供的校验码进行比较,如果两个值相同,表示数据没有错误;如果不同,则表示数据存在错误。

总结:CRC16查表法是一种高效的计算CRC16校验码的方法。

它通过使用一个查表数组来加快计算过程,从而提高了效率。

该方法的实现步骤较为简单,只需要按照特定的顺序对数据进行处理,并使用查表数组来获取校验码的新值。

通过比较接收方计算得到的校验码与发送方提供的校验码,可以判断数据是否正确。

因此,CRC16查表法被广泛应用于数据通信中,以确保数据的完整性和准确性。

modbus crc 查表法与计算法

modbus crc 查表法与计算法

Modbus是一种用于串行通信的协议,通常用于工业控制系统中的设备之间的通信。

在Modbus协议中,通信的数据经常需要进行CRC (循环冗余校验)校验以确保数据的准确性。

在实际应用中,我们可以通过查表法或计算法来计算Modbus协议中的CRC校验值。

本文将介绍Modbus CRC的查表法和计算法,并对这两种方法进行比较和分析。

一、Modbus CRC的概念及应用Modbus通信协议是一种用于工业控制系统的通信协议,它规定了设备之间的数据通信格式和规则。

在Modbus协议中,通信的数据需要进行CRC校验以确保数据的完整性和准确性。

CRC校验是一种通过对数据进行处理得到固定长度的校验码,用于校验数据传输的正确性的技术。

Modbus协议中的CRC校验值通常是16位的,可以通过CRC计算器进行计算,并将计算得到的校验值附加到数据传输中。

接收端收到数据后,同样可以通过计算CRC校验值来验证数据的正确性。

二、Modbus CRC的查表法1. 查表法是一种通过预先计算出CRC校验值并存储在表中,然后在实际使用时直接查表得到CRC校验值的方法。

对于Modbus协议中的CRC校验,可以使用一个256个元素的查表来进行计算。

2. 查表法的优点是计算速度快,适用于嵌入式系统或资源有限的设备。

由于CRC校验是通过查表得到的,因此不需要进行复杂的计算,可以节省系统资源和计算时间。

3. 但是查表法的缺点是需要额外的存储空间来存储CRC校验值的查表,对于一些资源有限的设备可能会造成存储空间的浪费。

三、Modbus CRC的计算法1. 计算法是一种通过数学计算来得到CRC校验值的方法。

对于Modbus协议中的CRC校验,可以使用多项式除法来进行计算。

2. 计算法的优点是不需要额外的存储空间来存储查表,因此不会造成存储空间的浪费。

而且计算法可以适用于任何系统,不受资源限制的影响。

3. 但是计算法的缺点是计算速度相对较慢,特别是对于资源有限的嵌入式系统或单片机来说,可能会影响系统的性能。

c语言crc校验程序查表法

c语言crc校验程序查表法

c语言crc校验程序查表法
(原创版)
目录
1.CRC 校验原理
2.C 语言 CRC 校验程序实现
3.查表法在 CRC 校验中的应用
4.实例:使用查表法实现 CRC 校验
正文
一、CRC 校验原理
CRC(Cyclic Redundancy Check,循环冗余校验)是一种基于二进制多项式的数据校验技术。

它通过在数据末尾附加一些校验位,然后接收方在接收到数据后,通过相同的计算方法,对数据进行校验,以判断数据在传输过程中是否发生了改变或损坏。

CRC 校验的主要优点是能够检测出大部分数据传输错误,且计算简单,易于实现。

二、C 语言 CRC 校验程序实现
C 语言中实现 CRC 校验的主要步骤如下:
1.首先,根据需要生成一个二进制多项式。

这个多项式可以是固定的,也可以是随机生成的。

2.将待校验的数据用二进制表示,并在数据末尾添加一些校验位,使得整个数据长度可以被二进制多项式整除。

3.使用二进制多项式去除数据,得到一个余数。

这个余数就是 CRC 校验的结果。

4.在接收端,使用相同的方法计算 CRC 校验结果,然后将其与发送端得到的结果进行比较。

如果二者相同,则认为数据传输正确;如果不同,
则认为数据发生了改变或损坏。

三、查表法在 CRC 校验中的应用
查表法是一种常用的 CRC 校验算法。

它通过预先计算一组 CRC 值,并将其存储在表格中。

在需要进行 CRC 校验时,只需要查找对应的 CRC 值即可。

这种方法的优点是计算速度快,节省存储空间。

crc16查表法中表格数据计算方法及实例

crc16查表法中表格数据计算方法及实例

最近在搞CRC校验,用的是CRC16标准,查看了很多资料发现很多讲的都是CRC16-CCITT标准,一直想弄明白CRC-16标准中的采用查表法的方式中那两个表格中的数是如何求出来的。

可惜没有一个文章仔细的讲,更没有文章给出实例来算一算。

一切只能靠自己了,谁让我喜欢寻根摸底呢。

研究了一下本站会员玉丫子的文章,自己琢磨了琢磨,终于知道是怎么算出来的了。

CRC16算法的生成多项式x^16 + x^15 + x^2 + 1,十六进制表示为0x8005。

CRC16常见的表格中的数据是按照先传输LSB,消息右移进寄存器来计算的。

因此需要判断寄存器的最低位LSB,同时要将0x8005按位颠倒后(0xA001)根据LSB的情况决定是否与寄存器异或即可。

CRC16的表格中对应的数依次为0~255计算出来的CRC值,因此,此处只选取其中一两个数作为实例计算CRC值。

具体步骤如下所示:1)从0~255中选取需要计算的数,将其对应的十六进制数放入一个长度为16的寄存器的低八位,高八位填充0;2)如果寄存器的末位LSB为1,将寄存器的数值右移1位,再与0xA001位异或,否则仅将寄存器右移1位;3)重复第2步,直到低八位全部右移出寄存器;4)寄存器中的值则为校验码。

从0~255中挑选2(对应0x02)计算其CRC值:0x02的CRC-16的表格计算(反向)00000000 00000010 <- 最低位LSB = 0,高八位填充000000000 000000010 右移,高位填充0,并舍弃最后一位----------------- 第一次计算00000000 00000001 <- LSB = 100000000 000000001 右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第二次10100000 00000001 <- LSB = 101010000 000000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第三次11110000 00000001 <- LSB = 101111000 000000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第四次11011000 00000001 <- LSB = 101101100 000000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第五次11001100 00000001 <- LSB = 101100110 000000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第六次11000110 00000001 <- LSB = 101100011 000000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 第七次11000011 00000001 <- LSB = 101100001 100000001右移,舍弃最后一位^10100000 00000001 <-与0xA001异或----------------- 一共右移了八次,得到的结果为CRC11000001 10000001 <- CRC: 0xC1 81从本文最后的附表中可以看出auchCRCHi[]的第三个值就是0x 81,auchCRCLo[]的第三个值就是0xC1,可见计算无误。

CRC16计算方法

CRC16计算方法

CRC-16校验码计算方法
常用查表法和计算法。

计算方法一般都是:
(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)进行异或;
(5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;(6)、重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;
(7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换;
(8)、最后得到的CRC寄存器内容即为:CRC码。

以上计算步骤中的多项式A001是8005按位颠倒后的结果。

查表法是将移位异或的计算结果做成了一个表,就是将0~256放入一个长度为16位的寄存器中的低八位,高八位填充0,然后将该寄存器与多项式0XA001按照上述3、4步骤,直到八位全部移出,最后寄存器中的值就是表格中的数据,高八位、低八位分别单独一个表。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

}
return ((chCRCHi << 8) | chCRCLo) ;
}
unsigned char data[9]={0x01, 0x10 ,0x00, 0x40 ,0x00, 0x01 ,0x02 ,0x07, 0xD0}; #define length 9 unsigned char *p[length]; void main() {
CRC16=*ptr^CRC16; for (j=0;j< 8;j++) {
tmp=CRC16 & 0x0001; CRC16 =CRC16 >>1; if (tmp) CRC16=CRC16 ^ 0xa001; } *ptr++; } return(CRC16); } void main() { for(j=0;j<10;j++) { p[j]=&data[j]; } CRC=crc16l(*p,length);
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,
int CRC=0; int j=0; for(j=0;j<10;j++) {
p[j]=&data[j]; }
CRC=CRC16_1(*p,length);
printf("CRC=%x\n",CRC);
}
*/
typedef unsigned char uchar;
typedef unsigned int
uint;
typedef unsigned short
uInt16;
uint CRC;
uint j;
uchar data[9]={0x01, 0x10 ,0x00, 0x40 ,0x00, 0x01 ,0x02 ,0x07, 0xD0};
#define length 9
uchar *p[length];
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,
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
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,
};
unsigned char chCRCLTalbe[] =
// CRC 低位字节值

{
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
CRC查表法+计算法.txt
#include"stdio.h"
/*
unsigned char chCRCHTalbe[] =
// CRC 高位字节值

{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
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,
};
unsigned int CRC16_1(unsigned char *pchMsg, unsigned int wDataLen) 第1页
CRC查表法+计算法.txt
{
unsigned char chCRCHi = 0xFF; // 高CRC字节初始化
unsigned char chCRCLo = 0xFF; // 低CRC字节初始化
unsigned char wIndex;
// CRC循-)
{
// 计算CRC
wIndex = chCRCLo ^ *pchMsg++ ;
chCRCLo = chCRCHi ^ chCRCHTalbe[wIndex];
chCRCHi = chCRCLTalbe[wIndex] ;
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,
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,
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, 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,
相关文档
最新文档