CRC16校验算法实现
CRC-16算法及其单片机实现
C2 1 =C 0
计算 CR 一1 C 6码 C n= X50X 4
C1 C9 = Co C8 X7 X6 X5 X4 = 0 0 0 0
行 处 理 一个 字 节 后 的 CR 校 验 码 与 当前 输 入 字节 的关 系 , 循 C 再
环 查 表 计算 获得 [ ] 2 。 - 3
《 业 控 制 计 算 机 ) 0 2年第 2 工 21 5卷第 7期 表 示 CR 1 C- 6校 检码 的第 i , 中第 1 位 其 5位 为 最 高 位 。D 表 示 输 入 信 息 码 字 节 的第 i , 中 位 其
第 0位 为 最 高 位 。 i 值 等 于 C X的 j
址 4 H 4 H 中 。 如 C3 0-7 例 1的值 , 首先 根 据 表 1中 的推 导 公式 , 将 X 与 ) 的值 相 异 或 ; 移 两 位 后 , 有 效 值 移 人 至 第 5位 ; 后 ( 6 右 将 最
C C一 6算 法 及 其 单 片 机 实 现 R 1
C C 1 算法及其单片机实现 R 一 6
P r l lCR — go i m n I lme t t n o MCU Co t a al C—1 Al rh a d mpe e 6 t na i n o nr o
需 要 逐 位进 行 异 或和 移 位 运 算 [ 。 ”
nodejs crc16modbus校验计算方法
Node.js CRC16 Modbus校验计算方法1. 引言在Modbus通信中,CRC16校验是一种常见的校验方式,用于验证通信数据的完整性和准确性。
Node.js作为一种流行的后端开发语言,提供了丰富的库和工具,可以方便地实现CRC16 Modbus校验的计算方法。
2. CRC16 Modbus校验原理CRC(Cyclic Redundancy Check)循环冗余校验是一种通过对数据进行多项式除法操作来检测传输过程中可能出现的错误的校验方法。
在Modbus通信中,使用的是CRC16(16位循环冗余校验)算法,其计算方法如下:- 初始化CRC寄存器为0xFFFF- 对每一个字节进行如下操作:- CRC = CRC XOR 字节- 循环8次:- 如果(CRC AND 1) = 1,则CRC = (CRC >> 1) XOR 0xA001- 否则,CRC = CRC >> 1- 最终CRC即为校验结果3. Node.js实现CRC16 Modbus校验计算方法在Node.js中,可以使用Buffer类和位运算符来实现CRC16 Modbus校验的计算方法。
以下是一个简单的实现示例:```javascriptfunction crc16Modbus(buffer) {let crc = 0xFFFF;for (let i = 0; i < buffer.length; i++) {crc = (crc ^ buffer[i]) & 0xFF;for (let j = 0; j < 8; j++) {if (crc & 0x01) {crc = (crc >> 1) ^ 0xA001;} else {crc = crc >> 1;}}}return crc;}```4. 使用示例可以将上述代码保存为一个js文件,然后在Node.js环境中引入该文件,并调用crc16Modbus函数来计算需要校验的数据的CRC16值。
CRC16校验算法实现
CRC16校验算法实现CRC16算法基于二进制位的异或和移位操作,它将数据按照二进制形式进行处理。
CRC16算法采用了多项式除法的思想,通过对数据进行除法运算并计算余数,生成一定长度的冗余校验码,用于检测数据是否出现错误。
1.首先,需要选择一个CRC-16生成多项式。
常用的生成多项式有多个,常见的有CRC-CCITT(0x1021)、CRC-IBM(0x8005)等。
生成多项式决定了CRC-16算法的性能和效果。
2.将待校验的数据按照二进制形式进行处理。
如果数据是字符串,则需要将字符串转换为二进制形式。
可以使用ASCII码表将每个字符转换为对应的二进制形式。
3.初始化CRC寄存器为一个指定的值(通常为0xFFFF)。
4.对数据进行逐位处理。
从高位到低位,逐位将数据与CRC寄存器进行异或操作。
如果结果为1,则进行一次右移操作。
如果结果为0,则直接进行一次右移操作。
重复该操作直到处理完所有的位。
5.当所有的位处理完成后,将CRC寄存器的当前值作为校验码。
下面是一个简单的CRC16算法实现的示例代码(基于CRC-CCITT生成多项式,0x1021):```pythondef crc16(data):crc = 0xFFFF # 初始化CRC寄存器为0xFFFF#CRC-CCITT生成多项式polynomial = 0x1021for byte in data:crc ^= (byte << 8) # 将数据与CRC寄存器进行异或操作for _ in range(8):if crc & 0x8000:crc = (crc << 1) ^ polynomialelse:crc <<= 1return crc & 0xFFFF#示例用法data = "hello world"data_bytes = [ord(c) for c in data] # 将字符串转换为对应的ASCII码列表checksum = crc16(data_bytes)print("CRC16校验码:", checksum)```在上述示例代码中,crc16函数接收一个数据参数,该数据参数可以是字符串、字节数组等形式。
CCITTCRC-16计算原理与实现
CCITTCRC-16计算原理与实现CCITT CRC-16计算原理与实现CRC的全称为Cyclic Redundancy Check,中⽂名称为循环冗余校验。
它是⼀类重要的线性分组码,编码和解码⽅法简单,检错和纠错能⼒强,在通信领域⼴泛地⽤于实现差错控制。
实际上,除数据通信外,CRC在其它很多领域也是⼤有⽤武之地的。
例如我们读软盘上的⽂件,以及解压⼀个ZIP⽂件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储⽅⾯的应⽤可略见⼀斑。
差错控制理论是在代数理论基础上建⽴起来的。
这⾥我们着眼于介绍CRC的算法与实现,对原理只能捎带说明⼀下。
若需要进⼀步了解线性码、分组码、循环码、纠错编码等⽅⾯的原理,可以阅读有关资料。
利⽤CRC进⾏检错的过程可简单描述为:在发送端根据要传送的k位⼆进制码序列,以⼀定的规则产⽣⼀个校验⽤的r位监督码(CRC码),附在原始信息后边,构成⼀个新的⼆进制码序列数共k+r位,然后发送出去。
在接收端,根据信息码和CRC码之间所遵循的规则进⾏检验,以确定传送中是否出错。
这个规则,在差错控制理论中称为“⽣成多项式”。
1 代数学的⼀般性算法在代数编码理论中,将⼀个码组表⽰为⼀个多项式,码组中各码元当作多项式的系数。
例如 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,则说明传输中⽆错误发⽣,否则说明传输有误。
crc16 citt false c语言
CRC16(循环冗余校验码)是一种通过对数据进行多项式除法来生成校验码的方法。
它通常用于数据传输过程中的错误检测和校验,以确保数据的完整性和准确性。
CITT False CRC16 是其中一种常见的CRC16 校验码算法,它采用了 CITT 标准的多项式生成 16 位的校验码。
在 C 语言中,我们可以通过编写相应的函数来实现 CITT False CRC16 校验码的生成和验证。
本文将对 CITT False CRC16 算法进行介绍,并提供一个基于 C 语言的实现示例。
一、CITT False CRC16 算法介绍CITT False CRC16 算法采用了多项式 0x1021(x^16 + x^12 + x^5 + 1)来生成 16 位的校验码。
该算法将数据与 0x8005 进行按位异或运算,然后将结果与 0x8408 进行按位取反操作。
最终得到的余数就是 16 位的 CRC16 校验码。
该算法在数据通信领域得到了广泛的应用,因其计算速度快、效果稳定而备受青睐。
二、CITT False CRC16 算法实现在 C 语言中实现 CITT False CRC16 算法并不复杂,我们可以编写一个函数来完成 CRC16 校验码的生成和验证。
以下是一个基于 C 语言的示例代码:```c#include <stdio.h>#include <stdint.h>// 定义 CITT False CRC16 多项式#define POLY 0x1021// 计算 CRC16 校验码uint16_t crc16(uint8_t *data, uint32_t len) {uint16_t crc = 0;for (uint32_t i = 0; i < len; i++) {crc = crc ^ (data[i] << 8);for (int j = 0; j < 8; j++) {if (crc 0x8000) {crc = (crc << 1) ^ POLY;} else {crc = crc << 1;}}}return crc;}int m本人n() {// 测试数据uint8_t test_data[] = {0x01, 0x02, 0x03, 0x04, 0x05};uint32_t data_len = sizeof(test_data) / sizeof(test_data[0]);// 计算 CRC16 校验码uint16_t crc_code = crc16(test_data, data_len);printf("CRC16 校验码为:04X\n", crc_code);return 0;}```以上示例代码中,我们定义了一个 crc16 函数来计算 CITT False CRC16 校验码,同时编写了一个 m本人n 函数来调用 crc16 函数并打印结果。
c#CRC-16MODBUS校验计算方法及异或校验算法
c#CRC-16MODBUS校验计算⽅法及异或校验算法⼗年河东,⼗年河西,莫欺少年穷学⽆⽌境,精益求精只要是代码,如下:///<summary>///低字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16LH(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc);return result;}///<summary>///⾼字节在前///</summary>///<param name="pDataBytes"></param>///<returns></returns>static byte[] CRC16HL(byte[] pDataBytes){ushort crc = 0xffff;ushort polynom = 0xA001;for (int i = 0; i < pDataBytes.Length; i++){crc ^= pDataBytes[i];for (int j = 0; j < 8; j++){if ((crc & 0x01) == 0x01){crc >>= 1;crc ^= polynom;}else{crc >>= 1;}}}byte[] result = BitConverter.GetBytes(crc).Reverse().ToArray() ;return result;}还有两个供⼤家验证的byte数组,如下:List<byte> llsst = new List<byte>() {0x79,0x79,0x01,0x01,0x00,0x1C,0x01,0x90,0x00,0x01,0x28,0xC3,0xC1,0x00,0xE9,0x9E,0x00,0x00,0x00,0x00,0x52,0x85,0x00,0x01,0x11,0x8E,0x15,0x02,0xD0,0x41,0x3E,0x02,0x0B var CrcLs3t22 = CRC16LH(llsst.ToArray());var CrcLs2t25 = CRC16HL(llsst.ToArray());低字节在前的结果为:83 9A⾼字节在前的结果为:9A 83异或校验算法:public static byte XOR_Check(List<byte> pbuf){int res = 0;int len = pbuf.Count;for (int i = 0; i < len; i++){res ^= pbuf[i];}return BitConverter.GetBytes(res)[0];}@天才卧龙的博客。
CRC16校验码移位算法及VHDL实现
) + 而
( 1 )
【 关键词】C R C校 验 移位 C R C I 6 V H D L
字系统设计 中己被广泛使用 。用硬件描述语言 ( VHDL) 实 现 C RC校 验 码 的 计 算 , 然 后 下 载到 F P GA 芯 片 中 , 硬 件 实 现 C RC校 验 , 与 软件实现相 比,对数据的传输速度影响较小 。 本文介绍一种 CR C1 6 校验码串行产生的方法 , 并给出了其 V HDL实现及仿真分析。
< <上 接 1 8 8页
( 4 )信 息查询 :可以查询患 者近期 的身 体状况和处方情况 。 1 _ 3 . 2中心数据端和监控端
数 据 服 务 器 结 构 如 图 6所 示 , 主 要 有 数 卫 星 链 路 发 送 到 北 斗 中 心 主 站 :北 斗 用 户 终 端 本 课 题 针 对 医 疗 改 革 中 出 现 的 问题 ,结 合
C RC 8 、C RC1 6和 C RC 3 2等 。计算 CR C校 验 码可 以用 串行和并行 的方法实现 。串行实现 电 1 C R C 校验原理 路结构简单 ,但 比较耗时 ,位数越多越费时。 在发送 方要 发送 的 K 位数据 码后 ,以一 并 行实 现 电路 结 构复 杂,但 节省 时间。本 文 定的规则产生 一个 r 位用 于校验的监督码 ,附 介 绍一种采 用 C R C1 6生成 多项 式 串行 移位产 加在原数据后面 ,构成 的信 息码 为 n = k + r 位, 生校 验码 的计算过程 。生成 多项式为 G ( x ) 因此 ,这种 编码 又 叫 ( n , k ) 码 。 接 收 方 根 据 = g l 6 x + g l 5 X ” + ……+ g l x + g o ,在实际使用中, 通 信 双 方 约 定 的 规 则 进 行 校 验 ,确 定 数 据 是 否 并 不 需要 考 虑 最 高 位 ,它 总 是 被 舍 弃 的 ,因 此 出错。这个规则即 “ 生 成 多 项 式 ” 。K 位 数 据 只要 考虑余 下 l 6个 数据位 。在 串行通信 中实 码表 示 为 M ( x ) , 选 择 合 适 的 CR C 生 成 多 现移位计算 C RC1 6 校验码的原理如图 1 所示。 项式 G ( x ) , G( x )的最高次幂为 r 。 把M ( x ) 图 l中0 为乘法 ,0为异或。
crc16算法原理
crc16算法原理
CRC16(循环冗余校验)是一种校验数据完整性的算法,可以找
出数据中的错误,用于检验传输过程中数据是否被错误地修改过,针
对数据传输过程中大量无意义码流及噪声对数据造成干扰等问题。
它
本质上是基于位运算(如异或运算)的特殊编码方法,经过这种编码,可以发现任何位级、字节级的改变,且此改变非常明显,以保证数据
的正确性。
是累加检验的实现。
它的一般过程是:首先把数据和一个
固定长度的码(最常用的是16位的CRC码)进行比较,如果数据中出
现改变,则导致码的改变,如果不一致,说明发生了数据错误;若一致,没有发生数据错误,则数据传输时正确。
CRC16校验方法
CRC校验算法CRC校验算法CRC(Cyclic Redundancy Check)循环冗余校验是常用的数据校验方法,讲CRC算法的文章很多,之所以还要写这篇,是想换一个方法介绍CRC算法,希望能让大家更容易理解CRC算法。
先说说什么是数据校验。
数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),如何发现误码呢?方法是发送额外的数据让接收方校验是否正确,这就是数据校验。
最容易想到的校验方法是和校验,就是将传送的数据(按字节方式)加起来计算出数据的总和,并将总和传给接收方,接收方收到数据后也计算总和,并与收到的总和比较看是否相同。
如果传输中出现误码,那么总和一般不会相同,从而知道有误码产生,可以让发送方再发送一遍数据。
CRC校验也是添加额外数据做为校验码,这就是CRC校验码,那么CRC校验码是如何得到的呢?非常简单,CRC校验码就是将数据除以某个固定的数(比如ANSI-CRC16中,这个数是0x18005),所得到的余数就是CRC校验码。
那这里就有一个问题,我们传送的是一串字节数据,而不是一个数据,怎么将一串数字变成一个数据呢?这也很简单,比如说2个字节B1,B2,那么对应的数就是(B1<<8)+B2;如果是3个字节B1,B2,B3,那么对应的数就是((B1<<16)+(B2<<8)+B3),比如数字是0x01,0x02,0x03,那么对应的数字就是0x10203;依次类推。
如果字节数很多,那么对应的数就非常非常大,不过幸好CRC只需要得到余数,而不需要得到商。
从上面介绍的原理我们可以大致知道CRC校验的准确率,在CRC8中出现了误码但没发现的概率是1/256,CRC16的概率是1/65536,而CRC32的概率则是1/2^32,那已经是非常小了,所以一般在数据不多的情况下用CRC16校验就可以了,而在整个文件的校验中一般用CRC32校验。
crc16校验算法c语言
crc16校验算法c语言crc16校验算法是一种常用的数据校验方法,它可以检测出数据传输或存储过程中的错误,并提供纠错的依据。
crc16校验算法的原理是将待校验的数据看作一个多项式,用一个固定的生成多项式对其进行除法运算,得到的余数就是crc16校验码。
生成多项式的选择会影响crc16校验算法的性能,不同的应用场景可能需要不同的生成多项式。
本文主要介绍一种常用的生成多项式,即CRC-CCITT,它的二进制表示为0x1021,十六进制表示为0x11021。
本文将介绍三种实现crc16校验算法c语言的方法,分别是按位计算、按半字节计算和按单字节计算。
这三种方法的原理都是基于生成多项式对数据进行除法运算,但是具体的实现方式有所不同,各有优缺点。
下面分别介绍这三种方法,并给出相应的c语言代码。
按位计算按位计算是最直接的实现方式,它是将待校验的数据和生成多项式按位进行异或运算,得到余数。
这种方法的优点是不需要额外的存储空间,缺点是效率较低,需要循环处理每一位数据。
按位计算的c语言代码如下:#include<stdint.h>#define CRC_CCITT 0x1021//生成多项式//函数名称:crc_cal_by_bit;按位计算CRC//函数参数:uint8_t * ptr;指向发送缓冲区的首字节// uint32_t len;要发送的总字节数//函数返回值:uint16_tuint16_t crc_cal_by_bit(uint8_t*ptr, uint32_t len) {uint32_t crc =0xffff; //初始值while (len--!=0) {for (uint8_t i =0x80; i !=0; i >>=1) { //处理每一位数据crc <<=1; //左移一位if ((crc &0x10000) !=0) //如果最高位为1,则异或生成多项式crc ^=0x11021;if ((*ptr & i) !=0) //如果当前数据位为1,则异或生成多项式crc ^= CRC_CCITT;}ptr++; //指向下一个字节}uint16_t retCrc = (uint16_t)(crc &0xffff); //取低16位作为结果return retCrc;}按半字节计算按半字节计算是对按位计算的优化,它是将待校验的数据和生成多项式按半字节(4位)进行异或运算,得到余数。
16位CRC校验原理与算法分析
16位CRC校验原理与算法分析2007-12-14 09:37这里,不讨论CRC的纠错原理以及为什么要选下面提及的生成多项式,只是针对以下的生成多项式,如何获得CRC校验码,作一个比较详细的说明。
标准CRC生成多项式如下表:名称生成多项式简记式* 标准引用CRC-4 x4+x+1 3ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8 x8+x6+x4+x3+x2+x1 0x5ECRC-12 x12+x11+x3+x+1 80FCRC-16 x16+x15+x2+1 8005 IBM SDLCCRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCSCRC-32 x32+x26+x23+...+x2+x+1 04C11DB7 ZIP, RAR, IEEE 802 LAN/FDDI, IEEE 1394, PPP-FCSCRC-32c x32+x28+x27+...+x8+x6+1 1EDC6F41 SCTP生成多项式的最高位固定的1,故在简记式中忽略最高位1了,如0x1021实际是0x11021。
I、基本算法(人工笔算):以CRC16-CCITT为例进行说明,CRC校验码为16位,生成多项式17位。
假如数据流为4字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0];数据流左移16位,相当于扩大256×256倍,再除以生成多项式0x11021,做不借位的除法运算(相当于按位异或),所得的余数就是CRC校验码。
发送时的数据流为6字节:BYTE[3]、BYTE[2]、BYTE[1]、BYTE[0]、CRC[1]、CRC[0];II、计算机算法1(比特型算法):1)将扩大后的数据流(6字节)高16位(BYTE[3]、BYTE[2])放入一个长度为16的寄存器;2)如果寄存器的首位为1,将寄存器左移1位(寄存器的最低位从下一个字节获得),再与生成多项式的简记式异或;否则仅将寄存器左移1位(寄存器的最低位从下一个字节获得);3)重复第2步,直到数据流(6字节)全部移入寄存器;4)寄存器中的值则为CRC校验码CRC[1]、CRC[0]。
crc16modbus校验计算方法python
CRC16 Modbus 校验计算方法 Python 实现本文介绍了 CRC16 Modbus 校验计算方法在 Python 语言中的实现过程,旨在为从事相关领域的开发人员提供参考。
CRC16 Modbus 校验计算方法,是一种在 Modbus 通信协议中使用的循环冗余校验(CRC)算法。
在 Python 中,我们可以通过编写一个简单的函数来实现 CRC16 Modbus 校验计算方法。
以下是具体的实现步骤:```pythondef crc16_modbus(data):"""按照 CRC16 Modbus 校验计算方法,对输入数据进行校验计算 """crc = 0x0000for i in range(0, len(data), 2):crc = crc ^ data[i]for j in range(8):if (crc & 0x8000):crc = (crc << 1) ^ 0x0001else:crc = crc << 1return crc```上述代码定义了一个名为`crc16_modbus`的函数,该函数接收一个字节串`data`作为输入参数,按照 CRC16 Modbus 校验计算方法对数据进行校验计算,并返回校验结果。
在函数内部,我们首先将 CRC 值初始化为 0x0000。
然后,通过一个双重循环,将输入数据中的每个字节进行异或运算,并将结果累加到 CRC 值中。
接下来,我们对 CRC 值进行 8 次右移操作,并在每次右移后检查 CRC 值是否包含最高位的 1。
如果包含,则将 CRC 值异或上一个奇数数(0x0001);否则,直接进行右移操作。
最后,函数返回计算得到的 CRC 值。
在实际使用中,我们可以将输入数据和计算得到的 CRC 值进行异或运算,以验证数据是否发生变化。
总之,通过上述 Python 代码实现,我们可以在 Python 语言中实现 CRC16 Modbus 校验计算方法。
CRC16算法及JAVA实现
CRC16算法及JAVA实现
一、CRC16算法
1、什么是CRC16算法
CRC(Cyclic Redundancy Check,循环冗余校验)是一种根据数据内
容计算出的特定的简短数值,用于传输数据内容的正确性检测。
CRC16算
法是CRC算法家族成员中的一种,它比较常用,所以也被发挥的比较广泛。
2、CRC16算法的原理
CRC16算法的原理是通过计算数据块的纠错码,并将其附加到被校验
数据块的末端,在解码的一端,将该纠错码与原始数据块一起发送,然后
再次计算该数据块的纠错码,如果重新计算出的纠错码与原始发送的纠错
码相同,则证明数据在传输过程中没有发生错误。
CRC16算法的工作过程如下:首先设置一个预设值,通常是一个16
位数据,方法是将这16位数据装入一个16位的寄存器中,这16位数据
称为预设值。
然后将待验证的数据与此预设值进行按位异或运算,在最后
一步,再将此16位异或运算得到的结果,仍存入这个16位寄存器中,并
将该16位寄存器的每一位上的值取出来,组成一个16位的CRC码即为所求。
二、CRC16算法的java实现
```
public class CRC16
/**
*计算CRC16校验码
*
*/
public static String getCRC(byte[] bytes) int CRC = 0x0000ffff;
int POLYNOMIAL = 0x0000a001;
int i, j;
for (i = 0; i < bytes.length; i++)
for (j = 0; j < 8; j++)。
CRC16常见几个标准的算法及C语言实现
CRC16常见⼏个标准的算法及C语⾔实现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异或多项式产⽣:如x16+x12+x5+1x16表⽰第16位为1,x5表⽰第5位为1(1 << 16) | (1 << 12) | (1 << 5) | (1) = 0x11021但是CRC16只取低16位,写成16进制数就是 0x1021CRC16的算法原理:1.根据CRC16的标准选择初值CRCIn的值。
2.将数据的第⼀个字节与CRCIn⾼8位异或。
crc16常见的标准算法及c语言实现
crc16常见的标准算法及c语言实现CRC16是一种常用的校验算法,用于检测数据传输或存储过程中是否发生错误。
CRC16有多种标准算法,其中最常见的是CRC-16-CCITT和CRC-16-XMODEM。
以下是CRC-16-CCITT的C语言实现:```c#include <stdint.h>uint16_t crc16_ccitt(uint8_t *data, size_t length) {uint16_t crc = 0xFFFF;while (length--) {crc ^= *data++ << 8;for (size_t i = 0; i < 8; i++) {if (crc & 0x8000) {crc = (crc << 1) ^ 0x1021;} else {crc <<= 1;}}}return crc;}```以下是CRC-16-XMODEM的C语言实现:```c#include <stdint.h>uint16_t crc16_xmodem(uint8_t *data, size_t length) { uint16_t crc = 0xFFFF;while (length--) {crc ^= *data++ << 8;for (size_t i = 0; i < 8; i++) {if (crc & 0x8000) {crc = (crc << 1) ^ 0x04C11DB7;} else {crc <<= 1;}}}return crc;}```需要注意的是,以上代码中的数据是按照字节顺序进行处理的,因此在使用时需要保证数据没有字节序问题。
另外,CRC算法的实现取决于具体的标准,不同的标准可能会使用不同的初始值、多项式和反转字节顺序等参数。
因此,在实际使用时需要根据具体的标准选择合适的实现方式。
CRC16校验算法实现
CRC16校验算法实现CRC16(Cyclic Redundancy Check)是一种常用的校验算法,用于检测和纠正数据传输中的错误。
CRC16校验算法利用一个16位的除数对待校验的数据进行多项式除法运算得到一个16位的校验码。
以下是关于CRC16校验算法的实现解释:1.CRC16多项式和初始值-CRC-16/CCITT(0x1021)多项式:x^16+x^12+x^5+1-CRC-16/XMODEM(0x8408)多项式:x^16+x^12+x^5+1-CRC-16/USB(0x8005)多项式:x^16+x^15+x^2+1另外,CRC16算法需要一个初始值作为起始状态,常用的初始值是0xFFFF。
2.算法步骤-初始化:将CRC寄存器初始值设置为0xFFFF。
-逐位计算:对每个数据位进行计算,包括数据的每个字节和最低的一位,直到所有位都被处理。
-异或操作:如果当前位为1,将CRC寄存器的值和多项式进行异或操作。
-位移操作:将CRC寄存器的值向右移动一位。
-判断:如果当前位为1,执行一个异或操作;否则,跳过这一步。
-重复:重复以上几个步骤,直到所有数据位都被处理。
-最终结果:得到的CRC寄存器就是CRC16校验码。
3.实际编程实现以下是使用Python语言实现CRC16校验算法的示例代码:```pythondef crc16(data):crc = 0xFFFFpoly = 0x1021for byte in data:crc ^= (byte << 8)for _ in range(8):if crc & 0x8000:crc = (crc << 1) ^ polyelse:crc <<= 1crc &= 0xFFFFreturn crc```这个函数`crc16`接受一个字节串作为输入,并返回计算得到的CRC16校验码。
4.使用示例以下是使用示例,演示如何使用上述的`crc16`函数计算CRC16校验码:```pythondata = b'Hello, World!' # 待校验的数据crc = crc16(data) # 计算CRC16校验码print(hex(crc)) # 输出十六进制格式的校验码```在该示例中,输入数据为字符串"Hello, World!",将其转换为字节串,然后调用`crc16`函数进行校验码计算,最后将结果以十六进制格式打印出来。
JavaCRC16MODBUS校验算法实现
JavaCRC16MODBUS校验算法实现/*** CRC校验算法⼯具类*/public class CRCUtil {public static String getCRC(String data) {data = data.replace(" ", "");int len = data.length();if (!(len % 2 == 0)) {return "0000";}int num = len / 2;byte[] para = new byte[num];for (int i = 0; i < num; i++) {int value = Integer.valueOf(data.substring(i * 2, 2 * (i + 1)), 16);para[i] = (byte) value;}return getCRC(para);}/*** 计算CRC16校验码** @param bytes* 字节数组* @return {@link String} 校验码* @since 1.0*/public static String getCRC(byte[] bytes) {// CRC寄存器全为1int CRC = 0x0000ffff;// 多项式校验值int POLYNOMIAL = 0x0000a001;int i, j;for (i = 0; i < bytes.length; i++) {CRC ^= ((int) bytes[i] & 0x000000ff);for (j = 0; j < 8; j++) {if ((CRC & 0x00000001) != 0) {CRC >>= 1;CRC ^= POLYNOMIAL;} else {CRC >>= 1;}}}// 结果转换为16进制String result = Integer.toHexString(CRC).toUpperCase();if (result.length() != 4) {StringBuffer sb = new StringBuffer("0000");result = sb.replace(4 - result.length(), 4, result).toString();}//⾼位在前地位在后return result.substring(2, 4) + result.substring(0, 2);// 交换⾼低位,低位在前⾼位在后// return result.substring(2, 4) + result.substring(0, 2);}public static String getCRC1(byte[] bytes) {/*ModBus 通信协议的 CRC ( 冗余循环校验码含2个字节, 即 16 位⼆进制数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CRC16校验算法实现(转)循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC。
它是利用除法及余数的原理来作错误侦测(Error Detecting)的。
实际应用时,发送装置计算出CRC值并随数据一同发送给接收装置,接收装置对收到的数据重新计算CRC并与收到的CRC相比较,若两个CRC值不同,则说明数据通讯出现错误。
根据应用环境与习惯的不同,CRC又可分为以下几种标准:①CRC-12码;②CRC-16码;③CRC-CCITT码;④CRC-32码。
CRC-12码通常用来传送6-bit字符串。
CRC-16及CRC-CCITT码则用是来传送8-bit字符,其中CRC-16为美国采用,而CRC-CCITT为欧洲国家所采用。
CRC-32码大都被采用在一种称为Point-to-Point的同步传输中。
下面着重是CRC-16检验码的生成过程。
CRC-16码由两个字节构成,在开始时CRC寄存器的每一位都预置为1,然后把CRC寄存器与8-bit的数据进行异或,之后对CRC寄存器从高到低进行移位,在最高位(MSB)的位置补零,而最低位(LSB,移位后已经被移出CRC寄存器)如果为1,则把寄存器与预定义的多项式码进行异或,否则如果 LSB为零,则无需进行异或。
重复上述的由高至低的移位8次,第一个8-bit数据处理完毕,用此时CRC寄存器的值与下一个8-bit数据异或并进行如前一个数据似的8次移位。
所有的字符处理完成后CRC寄存器内的值即为最终的CRC值。
下面为CRC16的计算过程,其中生成多项式为:X16+X15+X2+1:1.设置CRC寄存器,并给其赋值FFFF(hex)。
2.将数据的第一个8-bit字符与16位CRC寄存器的低8位进行异或,并把结果存入CRC寄存器。
3.CRC寄存器向右移一位,MSB补零,移出并检查LSB。
4.如果LSB为0,重复第三步;若LSB为1,CRC寄存器与生成多项式码相异或。
5.重复第3与第4步直到8次移位全部完成。
此时一个8-bit数据处理完毕。
6.重复第2至第5步直到所有数据全部处理完成。
7.最终CRC寄存器的内容即为CRC值。
校验码实现编写CRC校验程序有两种办法:一种为计算法,一种为查表法。
下面是查表法的C语言实现:校验码算法程序实现样例(C语言):// Test.cpp : Defines the entry point for the console application. #include "stdafx.h"static unsigned char auchCRCHi[]={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, 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,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, 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, 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, 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,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};static unsigned char auchCRCLo[]={0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 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, 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, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,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, 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};unsigned short CRC16(unsigned char* puchMsg, unsigned short usDataLen){unsigned char uchCRCHi = 0xFF ;unsigned char uchCRCLo = 0xFF ;unsigned char uIndex ;while (usDataLen--){uIndex = uchCRCHi ^ *puchMsg++;uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];uchCRCLo = auchCRCLo[uIndex];}return (uchCRCHi << 8 | uchCRCLo) ;};void main(int argc, char* argv[]){unsigned charsrc[21]={'1','2','3','6','3','4','2','3','4','2','9','8','7','3','6','5','2','8 ','9','3','5'};unsigned short code = CRC16(src,21);printf("the result is %d/n",code);}以下是Delphi实现的代码unit CRC16;interfaceusesWindows, SysUtils;function CRC(a_strPuchMsg:string):LongWord; implementationconstct_ArrayCRCHi: array[0..255] of LongWord=($00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41,$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0,$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40,$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1,$81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41,$00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1,$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41,$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40,$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1,$81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40,$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40,$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0,$80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40,$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41,$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0,$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41,$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0,$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40,$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1,$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41,$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,$80, $41, $00, $C1, $81, $40);ct_ArrayCRCLo:array[0..255] of LongWord=($00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06,$07, $C7, $05, $C5, $C4, $04, $CC, $0C, $0D, $CD,$0F, $CF, $CE, $0E, $0A, $CA, $CB, $0B, $C9, $09,$08, $C8, $D8, $18, $19, $D9, $1B, $DB, $DA, $1A,$1E, $DE, $DF, $1F, $DD, $1D, $1C, $DC, $14, $D4,$D5, $15, $D7, $17, $16, $D6, $D2, $12, $13, $D3,$11, $D1, $D0, $10, $F0, $30, $31, $F1, $33, $F3,$F2, $32, $36, $F6, $F7, $37, $F5, $35, $34, $F4,$3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE, $FA, $3A,$3B, $FB, $39, $F9, $F8, $38, $28, $E8, $E9, $29,$EB, $2B, $2A, $EA, $EE, $2E, $2F, $EF, $2D, $ED,$EC, $2C, $E4, $24, $25, $E5, $27, $E7, $E6, $26,$22, $E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60,$61, $A1, $63, $A3, $A2, $62, $66, $A6, $A7, $67,$A5, $65, $64, $A4, $6C, $AC, $AD, $6D, $AF, $6F,$6E, $AE, $AA, $6A, $6B, $AB, $69, $A9, $A8, $68,$78, $B8, $B9, $79, $BB, $7B, $7A, $BA, $BE, $7E,$7F, $BF, $7D, $BD, $BC, $7C, $B4, $74, $75, $B5,$77, $B7, $B6, $76, $72, $B2, $B3, $73, $B1, $71,$70, $B0, $50, $90, $91, $51, $93, $53, $52, $92,$96, $56, $57, $97, $55, $95, $94, $54, $9C, $5C,$5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B,$99, $59, $58, $98, $88, $48, $49, $89, $4B, $8B,$8A, $4A, $4E, $8E, $8F, $4F, $8D, $4D, $4C, $8C,$44, $84, $85, $45, $87, $47, $46, $86, $82, $42,$43, $83, $41, $81, $80, $40);function CRC(a_strPuchMsg:string):LongWord;varl_CRCHi, l_CRCLo, l_Index, l_DataLen, i:LongWord; beginl_DataLen:= Length(a_strPuchMsg);l_CRCHi := $FF ;l_CRCLo := $FF ;l_Index :=0;i:=1;while (i<=l_DataLen) dobeginl_Index := l_CRCHi xor Integer(a_strPuchMsg[i]);l_CRCHi := l_CRCLo xor ct_ArrayCRCHi[l_Index];l_CRCLo := ct_ArrayCRCLo[l_Index];Inc(i);end;Result:= (l_CRCHi shl 8) or l_CRCLo;end;end.。