2012-07-30 78 views
0

代碼(C語言編寫):CRC編程需要幫助,CRC32轉換從.NET類到C

unsigned long chksum_crc32 (unsigned char *block, unsigned int length) 
{ 
    register unsigned long crc; 
    unsigned long i; 

    crc = 0xFFFFFFFF; 
    for (i = 0; i < length; i++) 
    { 
     crc = ((crc >> 8) & 0x00FFFFFF)^crc_tab[(crc^*block++) & 0xFF]; 
    } 
    return (crc^0xFFFFFFFF); 
} 


/* chksum_crc32gentab() --  to a global crc_tab[256], this one will 
*    calculate the crcTable for crc32-checksums. 
*    it is generated to the polynom [..] 
*/ 

void chksum_crc32gentab() 
{ 
    unsigned long crc, poly; 
    int i, j; 

    poly = 0xEDB88320L; 
    for (i = 0; i < 256; i++) 
    { 
     crc = i; 
     for (j = 8; j > 0; j--) 
     { 
     if (crc & 1) 
     { 
      crc = (crc >> 1)^poly; 
     } 
     else 
     { 
      crc >>= 1; 
     } 
     } 
     crc_tab[i] = crc; 
    } 
} 

對於初學者;我知道CRC如何工作,首先用指定的多項式計算除數,然後將此FCS(幀校驗序列)附加到數據集併發送給最終用戶系統。一旦傳輸完成,FCS將被用於計算FCS的相同多項式進行檢查,如果該除數的其餘數據爲零,則您知道數據是正確的。

我不明白這兩個函數的實現。根據我所瞭解的,函數chksum_crc32gentab()會生成校驗和可以用32位CRC多項式進行檢測的所有可能的十六進制值。我沒有得到的一件事是如何poly = 0xEDB88320L;等價於一個多項式。我不明白這個函數底部的邏輯。例如,如果條件爲if(crc & 1),這是否意味着對於crc中的每一位是1,計算,否則右移一位?我也不懂chksum_crc32(unsigned char * block,unsigned int length);。這個函數是否只接收一串字節並將它們轉換爲使用表計算的合適的crc值?我想我對在for循環中使用的邏輯感到困惑。

如果有人瞭解這段代碼,解釋會很棒;這樣做的工作,用於從.NET類的CRC32轉換,數據如何被轉換然後用於通過這些功能會是這樣的一個示例: (C#源)

 MemoryStream ms = new MemoryStream(System.Text.Encoding.Default.GetBytes(input)); 

      foreach (byte b in crc32.ComputeHash(ms)) 
       hash += b.ToString("x2").ToLower(); 

這裏是原始站點並投影C代碼取自。 http://www.codeproject.com/Articles/35134/How-to-calculate-CRC-in-C

任何解釋將有助於

回答

3

在CRC計算中,具有0或1係數的x^n之和的二進制多項式簡單表示爲二進制字,其中0或1的位置指示哪個功率爲x這是一個係數。

0xEDB88320L將CRC32多項式的係數表示爲1,其中存在x^n項(除去x^32項,省略此項)。該CRC32多項式(!爲什麼啊,爲什麼不計算器具有TeX的方程一樣math.stackexchange - 我不能在這裏寫出像樣的方程嘆息,遺憾的咆哮...)是:

x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 

由於CRC是如何定義的,所以最低位的係數是最低的。所以上面的十六進制常量中的第一個E1110(代表從左到右依次排列),1 + x + x^2

你可以找到zlibcrc32.c源文件中的建築,從這裏所示的代碼段:

static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 

    /* make exclusive-or pattern from polynomial (0xedb88320UL) */ 
    poly = 0; 
    for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) 
     poly |= (z_crc_t)1 << (31 - p[n]); 

    /* generate a crc for every 8-bit value */ 
    for (n = 0; n < 256; n++) { 
     c = (z_crc_t)n; 
     for (k = 0; k < 8; k++) 
      c = c & 1 ? poly^(c >> 1) : c >> 1; 
     crc_table[0][n] = c; 
    } 

if (crc & 1)c & 1 ?上述着眼於CRC的低位,在之前它的每一步被轉移。這實際上是多項式減法運算的一個進位位,所以如果它是一個,則從CRC中的向下移位多項式中減去(排除)多項式(乘以x)。無論低位是1還是沒有,CRC都會下移。

您顯示的chksum_crc32()函數的確能計算所提供的數據塊上的CRC。它是標準的基於表格的方法,用於對字節串進行CRC計算,這些字節通過異或數據字節和CRC的低字節索引表。這與每次移入一點並將多項式應用於1位相同,但是隻需一步而不是八步。 CRC實際上乘以x^8>> 8),並且取決於索引值,在多個移位位置排斥多項式0至8次的排他性效果。這只是使用預先計算的表格的速度技巧。

您可以在zlib的crc32.c中找到使用更大表格並處理更多數據的更加極端的速度技巧。