2013-02-26 85 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