gpt4 book ai didi

Java 16位CRC数据包验证

转载 作者:行者123 更新时间:2023-12-01 05:06:39 24 4
gpt4 key购买 nike

我有一个 Avl 数据包,正在通过 GPRS 从设备接收。

协议(protocol)手册说数据包的最后4个字节有16位CRC,并给出了CRC计算的源代码:

public static int getCrc16(Byte[] buffer) {
return getCrc16(buffer, 0, buffer.length, 0xA001, 0);
}

public synchronized static int getCrc16(Byte[] buffer, int offset, int bufLen, int polynom, int preset) {
preset &= 0xFFFF;
polynom &= 0xFFFF;
int crc = preset;
for (int i = 0; i < bufLen; i++) {
int data = buffer[i + offset] & 0xFF;
crc ^= data;
for (int j = 0; j < 8; j++) {
if ((crc & 0x0001) != 0) {
crc = (crc >> 1) ^ polynom;
} else {
crc = crc >> 1;
}
}
}
return crc & 0xFFFF;
}

所以我得到了数据包发送给我的 CRC 编号,然后我为存储数据包的字节数组调用 getCrc16,然后比较这两个数字,对吗??

这是我在程序中使用的代码:

public static String toBinaryString(byte n) {
StringBuilder sb = new StringBuilder("00000000");
for (int bit = 0; bit < 8; bit++) {
if (((n >> bit) & 1) > 0) {
sb.setCharAt(7 - bit, '1');
}
}
return sb.toString();
}

int CalculatedCRC = getCrc16(AvlPacket);
System.out.println("Calculated CRC= " + CalculatedCRC);

int index = (AvlPacket.length)-4;
String BinaryRecievedCRC = "";

for (int j = 0; j < 4; j++) {
BinaryRecievedCRC+= toBinaryString(AvlPacket[index]);
index+=1;
}

int RecievedCRC = Integer.parseInt(BinaryRecievedCRC, 2);
System.out.println("Recieved CRC= " + RecievedCRC);

toBinaryString() 将字节转换为二进制并将其放入字符串中!

因此,我通过手册中提供的 getCrc16() 计算 CRC。然后在数据包末尾之前的 4 个字节处获取索引,这样我就可以读取最后 4 个字节并获取随数据包一起发送的 CRC!

for 循环获取最后的每个字节,并使用 toBinaryString() 将所有这些字节以二进制形式组合成一个字符串!所以我得到了类似 0000000000000000101011011101001 的内容(手册指出前两个字节始终为零,因为它是 16 位 CRC )

所以我只是将二进制字符串解析为有符号 int 并比较两个 CRC...!

但我得到的结果如下:

计算出的 CRC= 21395-----收到CRC=30416

计算出的 CRC= 56084-----收到CRC=10504

我已经测试了很多数据包,它们不可能都丢失数据。而且我也在解析数据,所以我知道我得到的数据是正确的!

我在这一切中错过了什么?

最佳答案

文档措辞(或您对它的理解)可能有问题。如果数据包中有 16 位 CRC,它很可能占用两个字节,而不是四个(二进制形式)。如果它是十进制,即使四个字节也不够(您需要 5 didgts 将其存储为无符号十进制字符串)。

您的代码显示您进行了转换(但我看不到它应该进行哪种转换):

BinaryRecievedCRC+= toBinaryString(AvlPacket[index]);

我希望 CRC 以二进制形式存储在数据中,因此我假设您唯一需要弄清楚的是使用哪种字节序以及 CRC 存储在数据中的位置。

编辑:从您的评论来看,您需要像这样提取 CRC:

public int getCRC(byte[] data, int index) {
return ((data[index] & 0xFF) << 8)) | (data[index + 1] & 0xFF);
}

关于Java 16位CRC数据包验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12565547/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com