C#中的CRC32失败

本文关键字:失败 CRC32 中的 | 更新日期: 2023-09-27 17:59:51

我试图在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的结果也是正确的。我做错了什么?

C#中的CRC32失败

这里的问题是您使用了错误的数据类型。我不熟悉CRC32算法,所以我在谷歌上搜索http://sanity-free.org/12/crc32_implementation_in_csharp.html作为参考实现。

我注意到的第一件事是他们使用CCD_ 2而不是CCD_。这是有道理的,因为我假设CRC32中的32意味着它将返回一个32位的数字。long是一个64位带符号的内部

如果你把所有的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