2013-02-26 84 views
0

我有这个函数,在Delhpi,计算传输消息的CRC。该函数应该返回一个2字节的CRC,但对于某些消息,CRC长度为3字节。德尔福字节操作和Java

下面是一些例子:

消息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)}; 
    } 

用这种方法我转换的十六进制字符串中的字节数组:

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,但无法给出正确的CRC的3层字节的信息... 任何帮助或想法? 谢谢, 佩德罗

+2

即使你只想要一个单独的操作,也总是在'if'和'else'中使用大括号。它会增加你的代码的可读性,并可能修复你当前的错误。根据你的代码格式,我猜你希望你的代码有其他行为。 – jlordo 2013-02-26 19:17:24

+1

你可以发布样本我/ P和O/P和预期的结果? – 2013-02-26 19:21:29

+0

从你说什么,我不能告诉你是否是你的问题的起源,但要小心,在Java中,字节是有符号的,当在Delphi中它是无符号的。 – 2013-02-26 19:24:28

回答

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中的字符串索引从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); 
+0

此建议将方法结果从083D9B更改为F34F93!:)正确答案是083D9B。谢谢 – Pedro 2013-02-26 19:35:22

+0

@Pedro:根据此评论,您当前的结果和正确的结果是相同的。你的问题解决了吗? – jlordo 2013-02-26 19:36:22

+0

你如何使用这种方法?我正在尝试'byte bytes [] = {0x05,(byte)0x88,0x08,0x01,0x68,(byte)0xF8}; byte [] calculateCRC = calculateCRC(bytes,bytes.length);'。那是你做的? – 2013-02-26 19:38:15