[英]CRC32 in C# fails
我試圖在C#中實現自己的CRC32函數。 我在這里的JS JavaScript CRC32中看到了一個優雅的解決方案,因此我想到了:
internal static class Crc32
{
internal static long CalculateCrc32(string str)
{
long[] crcTable = Crc32.MakeCrcTable();
long crc = 0 ^ (-1);
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
crc = (crc >> 8) ^ crcTable[(crc ^ c) & 0xFF];
}
return ~crc; //(crc ^ (-1)) >> 0;
}
internal static long[] MakeCrcTable()
{
long c;
long[] crcTable = new long[256];
for (int n = 0; n < 256; n++)
{
c = n;
for (int k = 0; k < 8; k++)
{
var res = c & 1;
c = (res == 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
}
crcTable[n] = c;
}
return crcTable;
}
}
問題是我的解決方案沒有返回相同的結果。 Console.WriteLine(Crc32.CalculateCrc32("l"));
結果為1762050814,而JS函數產生2517025534。JS結果也是正確的結果。 我究竟做錯了什么?
這里的問題是您使用了錯誤的數據類型。 我對CRC32算法不熟悉,因此我在Google上找到了http://sanity-free.org/12/crc32_implementation_in_csharp.html作為參考實現。
我注意到的第一件事是他們使用uint
而不是long
。 這很有意義,因為我假設CRC32中的32表示它將返回32位數字。 long
是一個64位帶符號的int。
如果你改變所有的long
為uint
那么我們幾乎得到了工作程序。 唯一行不通的是c=n
因為它無法隱式將int(n)轉換為uint(c)。 但是,由於我們知道n始終將是一個正整數,因此我們也可以將n更改為uint
類型。
這給我留下了:
internal static uint CalculateCrc32(string str)
{
uint[] crcTable = Crc32.MakeCrcTable();
uint crc = 0xffffffff;
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
crc = (crc >> 8) ^ crcTable[(crc ^ c) & 0xFF];
}
return ~crc; //(crc ^ (-1)) >> 0;
}
internal static uint[] MakeCrcTable()
{
uint c;
uint[] crcTable = new uint[256];
for (uint n = 0; n < 256; n++)
{
c = n;
for (int k = 0; k < 8; k++)
{
var res = c & 1;
c = (res == 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
}
crcTable[n] = c;
}
return crcTable;
}
使用此代碼, Console.WriteLine(Crc32.CalculateCrc32("l"));
按預期顯示2517025534
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.