小知识
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
参数模型
- NAME:参数模型名称。
- WIDTH:宽度,即CRC比特数。
- POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
- INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。
- REFIN:待测数据的每个字节是否按位反转,True或False。
- REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
- XOROUT:计算结果与此参数异或后得到最终的CRC值。
代码实现
public static int CRC_XModem(byte[] bytes) {
int crc = 0x00, poly = 0x1021;
for (byte b : bytes) {
for (int i = 0; i < 8; i++) {
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit) {
crc ^= poly;
}
}
}
return crc & 0xFFFF;
}
参数说明
- NAME:CRC-16/XMODEM
- WIDTH:16
- POLY:0x1021
- INIT:0x0000
- REFIN:False
- REFOUT:False
- XOROUT:0x0000
校验方式
public static boolean verify(byte[] bytes, String crc) {
return crc.equalsIgnoreCase(Integer.toHexString(CRC_XModem(bytes) & 0xFFFF));
}
测试代码
public static void main(String[] args) {
byte[] bytes = CommUtil.hex2Binary("68 28 00 05 FF 03".replaceAll(" ",""));
int hcs = CRC_XModem(bytes);
System.out.println((CommUtil.byteToHexString(hcs & 0xFF) + CommUtil.byteToHexString((hcs & 0xFF00) >> 8)).toUpperCase());
System.out.println(verify(bytes,"E6EB"));
}
外部参考
http://www.ip33.com/crc.html
感谢大佬提供这么牛毕的工具
评论区