2016-05-26 62 views
1

我已經提到了hackersdelight的CRC32實現,我只是從那裏編輯了crc32h函數,並讓它得到一個字節並更新最後一個CRC32值。因爲我需要用新的byte輸入來計算新的CRC32值。我可以通過向它發送一個數組來獲得它的工作,因爲在調用CRC32函數之前我無法將我的整個數據保存到數組中。所以我想更新前一個字節計算出的最後一個CRC32值。這裏是黑客的實現:更新C中的CRC32值

unsigned int crc32h(unsigned char *message) { 
    int i, crc; 
    unsigned int byte, c; 
    const unsigned int g0 = 0xEDB88320, g1 = g0>>1, 
     g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, 
     g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; 

    i = 0; 
    crc = 0xFFFFFFFF; 
    while ((byte = message[i]) != 0) { // Get next byte. 
     crc = crc^byte; 
     c = ((crc<<31>>31) & g7)^((crc<<30>>31) & g6)^
      ((crc<<29>>31) & g5)^((crc<<28>>31) & g4)^
      ((crc<<27>>31) & g3)^((crc<<26>>31) & g2)^
      ((crc<<25>>31) & g1)^((crc<<24>>31) & g0); 
     crc = ((unsigned)crc >> 8)^c; 
     i = i + 1; 
    } 
    return ~crc; 
} 

以下是我編輯的功能。

unsigned int crc32h(uint8_t byte,int crc) { 

    unsigned int c; 
    const unsigned int g0 = 0xEDB88320, g1 = g0>>1, 
     g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, 
     g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; 


    crc = crc^byte; 
    c = ((crc<<31>>31) & g7)^((crc<<30>>31) & g6)^
    ((crc<<29>>31) & g5)^((crc<<28>>31) & g4)^
    ((crc<<27>>31) & g3)^((crc<<26>>31) & g2)^
    ((crc<<25>>31) & g1)^((crc<<24>>31) & g0); 
    crc = ((unsigned)crc >> 8)^c; 

    crc = ~crc; 

    return crc; 
} 

此代碼計算CRC32值成功,如果我發送一個字節和default CRC value (0xFFFFFFFF)。但我無法更新CRC,例如:

int crc = 0xFFFFFFFF; 

crc = crc32h(0x11,crc); //This gives me the correct CRC32 for `0x11` 

crc = crc32h(0x22,crc); //But this does not give me the correct CRC32 for `0x1122` 

爲什麼它不更新有關以前CRC值的新CRC值?

+1

我想,如果你撥打電話' crc = crc32h(0x22,〜crc)',它會做你想做的。 –

+0

@JimMischel這也有效,但它需要以'0'而不是'0xFFFFFFFF'開頭。 –

+1

是的,我發表了這個評論,並且在馬丁貼出他的評論時正在寫一個答案。 –

回答

3

不同之處在於,第一個函數在消解所有字節後只反轉CRC一次, ,而編輯後的函數在處理每個單字節後反轉CRC CRC。

一個可能的解決方案可能是反轉的CRC也進入了 功能時:

unsigned int crc32h(uint8_t byte,int crc) { 

    unsigned int c; 
    const unsigned int g0 = 0xEDB88320, g1 = g0>>1, 
    g2 = g0>>2, g3 = g0>>3, g4 = g0>>4, g5 = g0>>5, 
    g6 = (g0>>6)^g0, g7 = ((g0>>6)^g0)>>1; 

    crc = ~crc; // <--- ADDED 
    crc = crc^byte; 
    c = ((crc<<31>>31) & g7)^((crc<<30>>31) & g6)^
    ((crc<<29>>31) & g5)^((crc<<28>>31) & g4)^
    ((crc<<27>>31) & g3)^((crc<<26>>31) & g2)^
    ((crc<<25>>31) & g1)^((crc<<24>>31) & g0); 
    crc = ((unsigned)crc >> 8)^c; 
    crc = ~crc; 

    return crc; 
} 

,並和0x0的,而不是0xFFFFFFFF的開始:

int crc = 0; 
crc = crc32h(0x11,crc); 
crc = crc32h(0x22,crc); 
+1

我正在輸入完全相同的答案... :-D – guga

+0

謝謝!我很長一段時間看不到這種差異,現在它工作:)我想我錯過了它,而刪除字符串的循環。 –