我有一个通过 GPRS 从设备接收的 Avl 数据包。
协议手册说数据包的最后 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)
所以我只是将二进制字符串解析为有符号整数并比较两个 CRC……!
然而我得到的结果如下:
计算出的 CRC= 21395 -----收到的 CRC= 30416
或者
计算的 CRC= 56084 -----收到的 CRC= 10504
我已经测试了很多数据包,它们不可能都丢失数据。我也在解析数据,所以我知道我得到的数据是正确的!
我在这一切中缺少什么?