2014-03-30 30 views
0

我正在修改that一段代碼以使其可以使用任意值和長度。使用任意值和長度的CRC計算

我至今修改:

public static int ModRTU_CRC(final byte[] buf, int crc) 
{ 
    final int len = buf.length; 

    for (int pos = 0; pos < len; pos++) 
    { 
     crc ^= buf[pos]; // XOR byte into least sig. byte of crc 

     for (int i = 8; i != 0; i--) 
     { // Loop over each bit 
      if ((crc & 0x0001) != 0) 
      { // If the LSB is set 
       crc >>= 1; // Shift right and XOR 0xA001 
       crc ^= 0xA001; 
      } 
      else 
      { 
       // Else LSB is not set 
       crc >>= 1; // Just shift right 
      } 
     } 
    } 
    // Note, this number has low and high bytes swapped, so use it 
    // accordingly (or swap bytes) 
    return crc; 
} 

我測試我的代碼以下列方式:

final String a = "1101011011"; 
final String crc = "10011"; 
final int parsedA = Integer.parseInt(a, 2); 
final ByteBuffer parsedBytes = ByteBuffer.allocate(4).putInt(parsedA); 
final byte[] array = parsedBytes.array(); 
final int parsedCRC = Integer.parseInt(crc, 2); 

System.out.println(Integer.toBinaryString(ModRTU_CRC(array, parsedCRC))); 

我得到1000111101000101但正確答案是11010110111110。即使我交換字節,我也沒有達到目標。你能幫我弄清楚我犯了什麼錯誤嗎?

+1

在鏈接代碼中,'crc'從0xFFFF開始,但是在這裏它開始於我們在代碼中看不到的其他值(取決於'b'的值)。它是否正確? – immibis

+0

正確,crc取決於b的值。在這種情況下'crc'將會是'0x13'。 –

+0

問題中的代碼不顯示「b」的值,因此您可能需要添加該值。另外,你是怎麼計算出「11010110111110」是正確答案的?另外,除了'crc'的起始值之外,這段代碼和鏈接代碼之間是否有區別? – immibis

回答

2

你很困惑。您嘗試的示例直接來自Ross William的CRC教程。您需要再次完整閱讀該教程,速度更慢,隨時隨地處理所有問題。

CRC和CRC多項式是兩回事。您的10011是教程中的CRC多項式,x + x + 1。您的1101011011是消息。從本教程中,用CRC多項式附加0000來劃分消息的其餘部分爲1110是CRC。這是一個四位CRC,因爲它使用四次多項式。

那麼你認爲你應該得到的是帶有CRC的消息,即11010110111110。這不是CRC。這是附有CRC的消息。該消息和附加的CRC具有如下性質:如果將它除以CRC多項式,則會得到餘數爲零。一旦CRC被計算出來,這就是正常傳輸的內容。

出於某種原因,你正試圖與使用的位CRC的不同多項式(的0xA001一個CRC常規執行此操作對多項式X + X + X + +1,反過來),從教程中的例子中提供CRC多項式到初始CRC應該在例程中去的位置(回想CRC和CRC多項式是兩個不同的東西),並提供10位消息作爲32位。此外,您將以big-endian順序(假設您沒有更改該字節緩衝區的順序)呈現消息,該消息首先提供一大堆零,並且您正在使用一次處理8位數據的例程,使得僅處理十位不可能。

你應該離開CRC例程,重新開始本教程。

+0

感謝那冗長的解釋。我現在看到,我修改並希望應用各種crc多項式和消息的算法不太合適,或者確切地說,它必須被修改得比我預期的更多。我會退後一步,嘗試從頭開始解決我的任務。 –