Java版CRC16-ModBus校验码
- 格式:docx
- 大小:24.31 KB
- 文档页数:5
crc16modbus函数CRC16Modbus函数是一个数据校验函数,用于检测Modbus通信协议中传输的数据,确保数据的完整性和正确性。
该函数的作用是使用16位的循环冗余校验码(CRC)来检测数据包是否有误。
下面我们逐步介绍CRC16Modbus函数的实现过程:一、定义参数在实现CRC16Modbus函数之前,我们需要明确函数所需的参数。
CRC16Modbus函数需要一个数据缓冲区和数据长度。
通常情况下,数据缓冲区是一个字符数组,数据长度代表了该数组中所含有的字节数。
二、初始化CRC寄存器在开始计算校验码之前,我们需要对CRC寄存器进行初始化。
在Modbus协议中,CRC寄存器被初始化为0xFFFF。
三、计算CRC校验码在计算CRC校验码过程中,我们需要将每一个数据字节带入算法,并且更新CRC寄存器的值。
计算CRC校验码的具体过程如下:1. 将数据字节逐个带入算法2. 将CRC寄存器的值右移8位,然后在低8位上进行异或运算3. 将CRC寄存器的值与0xFF进行与运算4. 查表取出相应的值5. 将CRC寄存器的值与该值进行异或运算四、返回校验码当所有的数据字节带入算法后,CRC寄存器即是数据包的CRC校验码。
返回CRC寄存器的值即可。
需要注意的是,在计算过程中,数据包的字节顺序可能会影响最后计算的结果。
Modbus协议中采用了大端字节序,也就是高位字节在前,低位字节在后的方式进行传输。
因此在计算CRC校验码时,也需要按照这种字节序进行计算。
总之,CRC16Modbus函数作为一个常用的数据校验函数,在Modbus通信协议中得到了广泛的应用。
理解并掌握该函数的实现过程,不仅可以提高代码的可读性和可重用性,还能够提高数据传输的准确性和安全性。
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值。
最详细易懂的CRC-16校验原理(附源程序)1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘和’取值的多项式一一对应。
例如:代码对应的多项式为X6+X4+X2+X+1,而多项式为X5+X3+X2+X+1对应的代码101111 o标准CRC生成多项式如下表:名称生成多项式简记式*标准引用CRC-4 x4+x+1 3 ITU G.704CRC-8 x8+x5+x4+1 0x31CRC-8 x8+x2+x1+1 0x07CRC-8x8+x6+x4+x3+x2+x10x5ECRC-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 SCTP3、CRC-16校验码的使用:现选择最常用的CRC-16校验,说明它的使用方法。
根据Modbus协议,常规485通讯的信息发送形式如下:地址功能码数据信息校验码1byte 1byte nbyte 2byteCRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。
例如:信息字段代码为:1011001,校验字段为:1010。
发送方:发出的传输字段为:1 0 1 1 0 0 1 1 0 10信息字段校验字段接收方:使用相同的计算方法计算出信息字段的校验码,对比接收到的实际校验码,如果相等及信息正确,不相等则信息错误;或者将接受到的所有信息除多项式,如果能够除尽,贝y 信息正确。
crc16校验码的原理CRC16校验码是一种常用的差错检测方法,广泛应用于通信和存储系统中。
它通过对数据进行多项式除法运算,生成一个16位的校验码,用于验证数据的完整性和准确性。
CRC,即循环冗余校验(Cyclic Redundancy Check),是一种通过对数据进行除法运算得到校验码的方法。
CRC16是其中一种常用的算法,它使用16位多项式进行运算。
CRC16校验码的生成过程如下:1. 首先,需要选取一个16位的生成多项式。
常用的生成多项式有多种,如CRC-16/CCITT、CRC-16/XMODEM等。
不同的生成多项式会导致校验码的计算结果不同。
2. 将要进行校验的数据看作一个二进制数,假设为D(x)。
在D(x)的最高位和最低位之间添加16个0,得到一个新的二进制数M(x)。
3. 将M(x)除以生成多项式,得到商Q(x)和余数R(x)。
商Q(x)被丢弃,只保留余数R(x)。
4. 将余数R(x)作为校验码,附加在原始数据的后面。
5. 接收方在接收到数据后,将数据和校验码一起进行CRC16校验。
将接收到的数据视为二进制数,与生成多项式进行除法运算。
如果余数为0,则校验通过,数据可信;如果余数不为0,则校验失败,数据存在错误。
CRC16校验码的特点如下:1. 计算简单快速:CRC16校验码的计算过程只需进行位运算和异或操作,计算速度较快。
2. 高效可靠:CRC16校验码具有较高的错误检测能力,可以有效地检测出数据传输中的单比特错误和多比特错误。
3. 校验简便:接收方只需对接收到的数据和校验码进行一次CRC16运算,即可判断数据的完整性。
4. 校验码长度适中:CRC16校验码的长度为16位,既不会增加太多的传输开销,又具备较好的错误检测能力。
需要注意的是,CRC16校验码只能检测出数据传输中的错误,而无法对数据进行纠错。
因此,在实际应用中,CRC16校验码通常与其他纠错方法(如重传机制)结合使用,以提高数据的可靠性和完整性。
package testCase;public class CRC16M {static final String HEXES = "0123456789ABCDEF";byte uchCRCHi = (byte) 0xFF;byte uchCRCLo = (byte) 0xFF;private static byte[] auchCRCHi = { 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40 };private static byte[] auchCRCLo= { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2,(byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05,(byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C,(byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE,(byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B,(byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8,(byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB,(byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF,(byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC,(byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7,(byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12,(byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0,(byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1,(byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36,(byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35,(byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD,(byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE,(byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39,(byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8,(byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A,(byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF,(byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4,(byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7,(byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3,(byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0,(byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63,(byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6,(byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64,(byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D,(byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA,(byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9,(byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9,(byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA,(byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D,(byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74,(byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6,(byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73,(byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50,(byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53,(byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57,(byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54,(byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F,(byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A,(byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58,(byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89,(byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E,(byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D,(byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85,(byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86,(byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41,(byte) 0x81, (byte) 0x80, (byte) 0x40 };public int value;public CRC16M() {value = 0;}public void update(byte[] puchMsg, int usDataLen) {int uIndex;// int i = 0;for (int i = 0; i < usDataLen; i++) {uIndex = (uchCRCHi ^ puchMsg[i]) & 0xff;uchCRCHi = (byte) (uchCRCLo ^ auchCRCHi[uIndex]);uchCRCLo = auchCRCLo[uIndex];}value= ((((int) uchCRCHi) << 8 | (((int) uchCRCLo) & 0xff))) & 0xffff;return;}public void reset() {value = 0;uchCRCHi = (byte) 0xff;uchCRCLo = (byte) 0xff;}public int getValue() {return value;}private static byte uniteBytes(byte src0, byte src1) {byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 })) .byteValue();_b0 = (byte) (_b0 << 4);byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 })) .byteValue();byte ret = (byte) (_b0 ^ _b1);return ret;}private static byte[] HexString2Buf(String src) {int len = src.length();byte[] ret = new byte[len / 2+2];byte[] tmp = src.getBytes();for (int i = 0; i < len; i += 2) {ret[i / 2] = uniteBytes(tmp[i], tmp[i + 1]);}return ret;}public static byte[] getSendBuf(String toSend){byte[] bb = HexString2Buf(toSend);CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();bb[bb.length-1]=(byte) (0xff & ri);bb[bb.length-2]=(byte) ((0xff00 & ri) >> 8);return bb;}public static boolean checkBuf(byte[] bb){CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();if(bb[bb.length-1]==(byte)(ri&0xff)&& bb[bb.length-2]==(byte) ((0xff00 & ri) >> 8))return true;return false;}public static String getBufHexStr(byte[] raw){if ( raw == null ) {return null;}final StringBuilder hex = new StringBuilder( 2 * raw.length );for ( final byte b : raw ) {hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));}return hex.toString();}/***@param args*/public static void main(String[] args) {// TODO Auto-generated method stubbyte[] sbuf = CRC16M.getSendBuf("010304f8003fac");System.out.println(CRC16M.getBufHexStr(sbuf));}}。
【转】crc16⼏种标准校验算法及c语⾔代码⼀、CRC16校验码的使⽤ 现选择最常⽤的CRC-16校验,说明它的使⽤⽅法。
根据Modbus协议,常规485通讯的信息发送形式如下: 地址功能码数据信息校验码 1byte 1byte nbyte 2byte CRC校验是前⾯⼏段数据内容的校验值,为⼀个16位数据,发送时,低8位在前,⾼8为最后。
例如:信息字段代码为: 1011001,校验字段为:1010。
发送⽅:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10 信息字段校验字段 接收⽅:使⽤相同的计算⽅法计算出信息字段的校验码,对⽐接收到的实际校验码,如果相等及信息正确,不相等则信息错误;或者将接受到的所有信息除多项式,如果能够除尽,则信息正确。
⼆、CRC16校验码计算⽅法 常⽤查表法和计算法。
计算⽅法⼀般都是: (1)、预置1个16位的寄存器值0xFFFF,称此寄存器为CRC寄存器; (2)、把第⼀个8位⼆进制数据(既通讯信息帧的第⼀个字节)与16位的CRC寄存器的低 8位相异或,把结果放于CRC寄存器,⾼⼋位数据不变; (3)、把CRC寄存器的内容右移⼀位(朝⾼位)⽤0填补最⾼位,并检查右移后的移出位; (4)、如果移出位为0:重复第3步(再次右移⼀位);如果移出位为1,CRC寄存器与⼀多 项式(A001)进⾏异或; (5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进⾏了处理; (6)、重复步骤2到步骤5,进⾏通讯信息帧下⼀个字节的处理; (7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的⾼、低 字节进⾏交换; (8)、最后得到的CRC寄存器内容即为:CRC码。
以上计算步骤中的多项式A001是8005按位颠倒后的结果。
查表法是将移位异或的计算结果做成了⼀个表,就是将0~256放⼊⼀个长度为16位的寄存器中的低⼋位,⾼⼋位填充0,然后将该寄存器与多项式0XA001按照上述3、4步骤,直到⼋位全部移出,最后寄存器中的值就是表格中的数据,⾼⼋位、低⼋位分别单独⼀个表。
import java.io.IOException;public class CRC16Checker {private static int[] index = new int[] { 16, 15, 2, 0 };private static int[] getBinary(String text) {StringBuffer num = new StringBuffer();String s; char ch;for (int i = 0; i < text.length(); i++) { // Change each char to binary code.s = Integer.toBinaryString(text.charAt(i));// If the code is less than 8 bit, make it as 8 bit.for (int j = 8 - s.length(); j > 0; j--) num.append(0);num.append(s);}int len = num.length();int[] code = new int[len];for (int i = 0; i < len; i++) // Change each 0/1 char to int.code[i] = Character.getNumericValue(num.charAt(i));return code;}private static String toHex(int[] num) {StringBuffer hex = new StringBuffer(num.length / 4);char[] ch = new char[4];for (int i = 0; i < num.length;) {// Change each 0/1 int to char.ch[0] = Character.forDigit(num[i++], 2);ch[1] = Character.forDigit(num[i++], 2);ch[2] = Character.forDigit(num[i++], 2);ch[3] = Character.forDigit(num[i++], 2);// Change each 4-bit-code to hex number.hex.append(Integer.toHexString(Integer.parseInt(String.valueOf(ch), 2)));}return hex.toString();}// CRC codes main processpublic static int[] makeCRCCodes(int[] sourceCodes, int[] multinomial) {// The lenght of CRC code is N bits longer than source code. The codes// from 0 to sourceLength are same as the source. N bits aftersource// are the CRC codes. N is decided by the multinomial.// CRC码数组总长为原码长加上校验码码长。
modbus crc校验码计算原理Modbus CRC校验码计算原理介绍Modbus是一种常用的通信协议,广泛应用于工业控制系统中。
它采用CRC校验码对数据进行完整性验证,以确保数据的准确传输。
本文将从浅入深地解释Modbus CRC校验码计算的原理。
CRC校验码简介•CRC(Cyclic Redundancy Check)是一种循环冗余校验码,用于检测数据传输过程中是否出现错误。
•CRC校验码是通过将数据按位异或计算得出的,具有很强的验证能力。
•Modbus采用16位的CRC校验码,通常表示为4个十六进制数。
CRC校验码计算过程CRC校验码的计算过程如下:1.初始化一个16位的寄存器,将其置为全1。
2.对每个输入字节,将其与寄存器的低字节进行异或运算,得到一个结果。
3.将寄存器右移1位。
4.如果上一步的结果最低位为1,将寄存器与一个预设的固定值(0xA001)进行异或运算。
5.重复步骤2~4,直到所有输入字节处理完毕。
6.最终得到的寄存器值即为CRC校验码。
示例假设要计算以下输入数据的CRC校验码:0x01 0x02 0x03。
1.初始化寄存器为全1(0xFFFF)。
2.将输入数据0x01与寄存器低字节(0xFF)进行异或运算,得到结果0xFE。
3.将寄存器右移1位,得到0x7F。
4.由于上一步的结果最低位为1,将寄存器与预设固定值0xA001进行异或运算,得到0x3F01。
5.重复步骤2~4,依次处理输入数据0x02和0x03。
6.最终得到的寄存器值为CRC校验码,即0x3F01。
总结CRC校验码是Modbus通信中重要的数据完整性验证手段。
通过将数据进行位异或运算,并结合预设固定值,可以计算出16位的校验码。
通过比较接收到的校验码和计算得出的校验码,可以判断数据传输是否发生错误。
CRC校验的原理CRC校验码由于其简单而高效的计算方法,广泛应用于数据传输中。
其原理可以通过简单的位运算来理解。
Java接收端CRC16校验CRC16效验第一种public class CRC16 {private short[] crcT able = new short[256];private int gPloy = 0x8005; // 生成多项式public CRC16() {computeCrcTable();}private short getCrcOfByte(int aByte) {int value = aByte << 8;for (int count = 7; count >= 0; count--) {if ((value & 0x8000) != 0) { // 高第16位为1,可以按位异或value = (value << 1) ^ gPloy;} else {value = value << 1; // 首位为0,左移}}value = value & 0xFFFF; // 取低16位的值return (short)value;}/** 生成0 - 255对应的CRC16校验码*/private void computeCrcTable() {for (int i = 0; i < 256; i++) {crcTable[i] = getCrcOfByte(i);}}public short getCrc(byte[] data) {int crc = 0;int length = data.length;for (int i = 0; i < length; i++) {crc = ((crc & 0xFF) << 8) ^ crcTable[(((crc & 0xFF00) >> 8) ^ data[i]) & 0xFF];}crc = crc & 0xFFFF;return (short)crc;}}public final class CodecUtil {static CRC16 crc16 = new CRC16();private CodecUtil() {}public static byte[] short2bytes(short s) {byte[] bytes = new byte[2];for (int i = 1; i >= 0; i--) {bytes[i] = (byte)(s % 256);s >>= 8;}return bytes;}public static short bytes2short(byte[] bytes) { short s = (short)(bytes[1] & 0xFF);s |= (bytes[0] << 8) & 0xFF00;return s;}/** 获取crc校验的byte形式*/public static byte[] crc16Bytes(byte[] data) { return short2bytes(crc16Short(data));}/** 获取crc校验的short形式*/public static short crc16Short(byte[] data) { return crc16.getCrc(data);}public static void main(String[] args) {byte[] test = new byte[] {0, 1, 2, 3, 4};byte[] crc = crc16Bytes(test);byte[] testc = new byte[test.length + 2];for (int i = 0; i < test.length; i++) {testc[i] = test[i];}testc[test.length] = crc[0];testc[test.length + 1] = crc[1];System.out.println(crc16Short(testc)); }}。
package com.crc16.test;publicclass CRC16M {//定义常量privatestaticfinal String HEXES = "0123456789ABCDEF";privatebyte uchCRCHi = (byte) 0xFF;privatebyte uchCRCLo = (byte) 0xFF;privatestaticbyte[] auchCRCHi = {0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40};privatestaticbyte[] auchCRCLo = {(byte) 0x00, (byte) 0xC0, (byte) 0xC1,(byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA,(byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40};publicint value;public CRC16M() {value = 0;}publicvoid update(byte[] puchMsg, int usDataLen) {int uIndex;// inti = 0;for (int i = 0; i<usDataLen; i++) {uIndex = (uchCRCHi ^ puchMsg[i]) & 0xff;uchCRCHi = (byte) (uchCRCLo ^ auchCRCHi[uIndex]);uchCRCLo = auchCRCLo[uIndex];}value= ((((int) uchCRCHi) << 8 | (((int) uchCRCLo) & 0xff))) & 0xffff;return;}publicvoid reset() {value = 0;uchCRCHi = (byte) 0xff;uchCRCLo = (byte) 0xff;}publicint getValue() {return value;}privatestaticbyte uniteBytes(byte src0, byte src1) {byte _b0 = Byte.decode("0x" + new String(newbyte[] { src0 })) .byteValue();_b0 = (byte) (_b0 << 4);byte _b1 = Byte.decode("0x" + new String(newbyte[] { src1 })) .byteValue();byte ret = (byte) (_b0 ^ _b1);return ret;}privatestaticbyte[] HexString2Buf(String src) {int len = src.length();byte[] ret = newbyte[len / 2+2];byte[] tmp = src.getBytes();for (int i = 0; i<len; i += 2) {ret[i / 2] = uniteBytes(tmp[i], tmp[i + 1]);}return ret;}publicstaticbyte[] getSendBuf(String toSend){byte[] bb = HexString2Buf(toSend);CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();bb[bb.length-1]=(byte) (0xff &ri);bb[bb.length-2]=(byte) ((0xff00 &ri) >> 8);return bb;}publicstaticboolean checkBuf(byte[] bb){CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();if(bb[bb.length-1]==(byte)(ri&0xff)&&bb[bb.length-2]==(byte) ((0xff00 &ri) >> 8)) returntrue;returnfalse;}publicstatic String getBufHexStr(byte[] raw){if ( raw == null ) {returnnull;}final StringBuilder hex = new StringBuilder( 2 * raw.length );for ( finalbyte b : raw ) {hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));}return hex.toString();}/*** @param args*/publicstaticvoid main(String[] args) {// TODO Auto-generated method stubbyte[] sbuf =CRC16M.getSendBuf("1FF132003F020000160815080009F1F1130727000047F0F01608 150800FF0E12000000000020000019000018000018000019FF030C00000263024602590 26502493812070103");System.out.println(CRC16M.getBufHexStr(sbuf));//打印结果//1FF132003F020000160815080009F1F1130727000047F0F01608150800FF0E120 00000000020000019000018000018000019FF030C000002630246025902650249381207 010308CD//末端08CD 为2字节校验码//校验码会与部分校验工具相反,请自行调整。
javaCRC16算法1.CRC16算法public class CRC16Util {/*** 计算CRC16校验码** @param bytes* @return*/public static String getCRC(byte[] bytes) {int 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;}}}return Integer.toHexString(CRC);}/*** 查表法计算CRC16校验** @param data 需要计算的字节数组*/public static String getCRC3(byte[] data) {byte[] crc16_h = {(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte};byte[] crc16_l = {(byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte(byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, ((byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte(byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte(byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte(byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte(byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte(byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54 (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte(byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte(byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 };int crc = 0x0000ffff;int ucCRCHi = 0x00ff;int ucCRCLo = 0x00ff;int iIndex;for (int i = 0; i < data.length; ++i) {iIndex = (ucCRCLo ^ data[i]) & 0x00ff;ucCRCLo = ucCRCHi ^ crc16_h[iIndex];ucCRCHi = crc16_l[iIndex];}crc = ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;//⾼低位互换,输出符合相关⼯具对Modbus CRC16的运算crc = ( (crc & 0xFF00) >> 8) | ( (crc & 0x00FF ) << 8);return String.format("%04X", crc);}public static String getCRC2(byte[] bytes) {// ModBus 通信协议的 CRC ( 冗余循环校验码含2个字节, 即 16 位⼆进制数。
package com.crc16.test;publicclass CRC16M {//定义常量privatestaticfinal String HEXES = "0123456789ABCDEF";privatebyte uchCRCHi = (byte) 0xFF;privatebyte uchCRCLo = (byte) 0xFF;privatestaticbyte[] auchCRCHi = {0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40};privatestaticbyte[] auchCRCLo = {(byte) 0x00, (byte) 0xC0, (byte) 0xC1,(byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA,(byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40};publicint value;public CRC16M() {value = 0;}publicvoid update(byte[] puchMsg, int usDataLen) {int uIndex;// inti = 0;for (int i = 0; i<usDataLen; i++) {uIndex = (uchCRCHi ^ puchMsg[i]) & 0xff;uchCRCHi = (byte) (uchCRCLo ^ auchCRCHi[uIndex]);uchCRCLo = auchCRCLo[uIndex];}value= ((((int) uchCRCHi) << 8 | (((int) uchCRCLo) & 0xff))) & 0xffff;return;}publicvoid reset() {value = 0;uchCRCHi = (byte) 0xff;uchCRCLo = (byte) 0xff;}publicint getValue() {return value;}privatestaticbyte uniteBytes(byte src0, byte src1) {byte _b0 = Byte.decode("0x" + new String(newbyte[] { src0 })) .byteValue();_b0 = (byte) (_b0 << 4);byte _b1 = Byte.decode("0x" + new String(newbyte[] { src1 })) .byteValue();byte ret = (byte) (_b0 ^ _b1);return ret;}privatestaticbyte[] HexString2Buf(String src) {int len = src.length();byte[] ret = newbyte[len / 2+2];byte[] tmp = src.getBytes();for (int i = 0; i<len; i += 2) {ret[i / 2] = uniteBytes(tmp[i], tmp[i + 1]);}return ret;}publicstaticbyte[] getSendBuf(String toSend){byte[] bb = HexString2Buf(toSend);CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();bb[bb.length-1]=(byte) (0xff &ri);bb[bb.length-2]=(byte) ((0xff00 &ri) >> 8);return bb;}publicstaticboolean checkBuf(byte[] bb){CRC16M crc16 = new CRC16M();crc16.update(bb, bb.length-2);int ri = crc16.getValue();if(bb[bb.length-1]==(byte)(ri&0xff)&&bb[bb.length-2]==(byte) ((0xff00 &ri) >> 8)) returntrue;returnfalse;}publicstatic String getBufHexStr(byte[] raw){if ( raw == null ) {returnnull;}final StringBuilder hex = new StringBuilder( 2 * raw.length );for ( finalbyte b : raw ) {hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));}return hex.toString();}/*** @param args*/publicstaticvoid main(String[] args) {// TODO Auto-generated method stubbyte[] sbuf =CRC16M.getSendBuf("1FF132003F020000160815080009F1F1130727000047F0F01608 150800FF0E12000000000020000019000018000018000019FF030C00000263024602590 26502493812070103");System.out.println(CRC16M.getBufHexStr(sbuf));//打印结果//1FF132003F020000160815080009F1F1130727000047F0F01608150800FF0E120 00000000020000019000018000018000019FF030C000002630246025902650249381207 010308CD//末端08CD 为2字节校验码//校验码会与部分校验工具相反,请自行调整。