我在Delhpi中有这个函数来计算传输消息的CRC。此函数应返回2字节CRC,但对于某些消息,CRC长度为3字节。
以下是几个例子:
消息0588080168F8 - > CalculateCRC(0588080168F8,5)= 083D9B(3字节)
消息0588080168F0 - > CalculateCRC(0588080168F0,5)= BC93(2字节)
这是原始的delphi代码:
procedure CalculateCRC(var Message: TMessage);
var
counter: byte;
counter1: byte;
begin
for counter := 1 to Message.MessageLength + 1 do
begin
if counter = 1 then
Message.CRC := 0 xor (word(Message.MessageLength) shl 8)
else
Message.CRC := Message.CRC xor (word(Message.Data[counter-1]) shl 8);
for counter1 := 1 to 8 do
begin
if (Message.CRC and $8000) = $8000 then
Message.CRC := (Message.CRC shl 1) xor $1021
else
Message.CRC := Message.CRC shl 1;
end;
end;
end;
这是我的Java函数:
public static byte[] calculateCRC(byte[] msg, int len)
{
int crc=0;
for(int i=1; i<=len+1;i++)
{
if(i==1)
crc= 0 ^ (len<<8);
else
crc=crc ^ ((msg[i-1] & 0xff) << 8);
for(int j=1; j<=8;j++)
{
if((crc & 0x8000) == 0x8000)
crc= (crc <<1 ) ^ 0x1021;
else
crc= (crc <<1 ) ;
}
}
return new byte[] {(byte)((crc >>16) & 0xff),(byte) ((crc>>8) & 0xff),(byte)(crc & 0xff)};
}
使用此方法,我将字节数组中的HEX字符串转换为:
private static byte[] hexToBytes(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;
}
我的代码适用于2个字节的CRC,但无法在3个字节的消息上给出正确的CRC ... 任何帮助或想法? 谢谢, 佩德罗
答案 0 :(得分:2)
在Delphi代码的这一部分:
for counter := 1 to Message.MessageLength + 1 do
begin
if counter = 1 then
Message.CRC := 0 xor (word(Message.MessageLength) shl 8)
else
Message.CRC := Message.CRC xor (word(Message.Data[counter-1]) shl 8);
您从1开始计数到MessageLength + 1。并且逻辑似乎暗示Message.Data中的第一个索引是1.所以我猜这个代码是基于Delphi中的String索引从1开始的事实。但是在Java中并非如此,它们从0开始。所以你应该用这种方式重写你的Java方法:
for (int i = 0; i <= len; i++)
{
if (i == 0)
crc = 0 ^ (len << 8);
else
crc = crc ^ ((msg[i - 1] & 0xff) << 8);