crc16实现java

问题描述 投票:0回答:4

我在计算 java 中字节数组的 CRC-16 实现时遇到问题。基本上,我试图将字节发送到开始写入标签的 RFID。我可以通过在Mac上查看tcpdump命令来查看数组的校验和值。但我的目标是自己生成它。这是我的字节数组,它应该生成 0xbe,0xd9:

byte[] bytes = new byte[]{(byte) 0x55,(byte) 0x08,(byte) 0x68, (byte) 0x14, 
                          (byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00, 
                          (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, 
                          (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, 
                          (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, 
                          (byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11};

0x55 是标头。正如文档所说,它将被排除在外。

每当我在java上尝试这个数组(使用0xbe,0xd9)时,RFID就会起作用。我的问题是生成这些校验和值。我几乎搜索了整个网络,但没有机会。我找不到任何产生 0xbe,0xd9 的算法。

任何想法对我来说都是非常受欢迎的。预先感谢。

编辑:这里是 rfid 提供的协议

byte implementation crc rfid crc16
4个回答
3
投票

不太确定这是否是C crc16算法在Java中的正确翻译...... 但它显示了您的示例的正确结果!

使用前请先将其他结果与Mac的CRC16进行比较并进行压力测试

public class Crc16 { public static void main(String... a) { byte[] bytes = new byte[] { (byte) 0x08, (byte) 0x68, (byte) 0x14, (byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11 }; byte[] byteStr = new byte[4]; Integer crcRes = new Crc16().calculate_crc(bytes); System.out.println(Integer.toHexString(crcRes)); byteStr[0] = (byte) ((crcRes & 0x000000ff)); byteStr[1] = (byte) ((crcRes & 0x0000ff00) >>> 8); System.out.printf("%02X\n%02X", byteStr[0],byteStr[1]); } int calculate_crc(byte[] bytes) { int i; int crc_value = 0; for (int len = 0; len < bytes.length; len++) { for (i = 0x80; i != 0; i >>= 1) { if ((crc_value & 0x8000) != 0) { crc_value = (crc_value << 1) ^ 0x8005; } else { crc_value = crc_value << 1; } if ((bytes[len] & i) != 0) { crc_value ^= 0x8005; } } } return crc_value; } }
    

3
投票
Java 运行时中已经有 CRC16 实现 (

rt.jar

)。

源代码请参见

GitHub

如果您搜索 CRC16,您可能能够在 IDE 中看到它:


0
投票
也许您正在寻找这个?

java中的Crc16

我在此方法中使用相同的数组(变量“table”):

public Integer computeCrc16(byte[] data) { int crc = 0x0000; for (byte b : data) { crc = (crc >>> 8) ^ table[((crc ^ b) & 0xff)]; } return (int) crc; }
    

0
投票
如果您想要 ASCII 字符,请更改

byte[] bytes="02303131313233343031303345303903".getBytes();

以下是十六进制输入的正确答案, byte[] 字节 = hexStringToByteArray("02303131313233343031303345303903");

公开课 CRC16 {

public static void main(String[] args) { int[] table = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, }; byte[] bytes = hexStringToByteArray("02303131313233343031303345303903"); // for HEX int crc16 = 0x0000; for (byte b : bytes) { crc16=table[(crc16 ^ b) & 0xff] ^ (crc16 >> 8); } crc16= crc16 & 0xFFFF; System.out.println("CRC16 = " +Integer.toHexString(crc16)); } public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)+ Character.digit(s.charAt(i+1), 16)); } return data; }

}

© www.soinside.com 2019 - 2024. All rights reserved.