C#中的CRC32故障

C#中的CRC32故障,c#,crc32,C#,Crc32,我试图在C#中实现我自己的CRC32函数。我在JS中看到了一个优雅的解决方案 所以我想到了这个: internal static class Crc32 { internal static long CalculateCrc32(string str) { long[] crcTable = Crc32.MakeCrcTable(); long crc = 0 ^ (-1); for

我试图在C#中实现我自己的CRC32函数。我在JS中看到了一个优雅的解决方案 所以我想到了这个:

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;
        }
    }
内部静态类Crc32
{
内部静态长计算器ECRC32(字符串str)
{
long[]crcTable=Crc32.MakeCrcTable();
长crc=0^(-1);
对于(int i=0;i>8)^crcTable[(crc^c)&0xFF];
}
返回~crc;//(crc^(-1))>>0;
}
内部静态long[]MakeCrcTable()
{
长c;
long[]crcTable=新长[256];
对于(int n=0;n<256;n++)
{
c=n;
对于(int k=0;k<8;k++)
{
var-res=c&1;
c=(res==1)?(0xEDB88320^(c>>1)):(c>>1);
}
crcTable[n]=c;
}
返回crcTable;
}
}

问题是我的解决方案没有返回相同的结果<代码>控制台.WriteLine(Crc32.CalculateRC32(“l”)生成1762050814,而JS函数生成2517025534。JS结果也是正确的。我做错了什么?

这里的问题是您使用了错误的数据类型。我不熟悉CRC32算法,所以我在谷歌上找到了一个参考实现

我注意到的第一件事是他们正在使用
uint
而不是
long
。这是有道理的,因为我假设CRC32中的32表示它将返回一个32位的数字
long
是一个64位有符号整数

如果您更改
uint
的所有
long
,那么我们几乎可以得到一个工作程序。唯一不起作用的行是
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;
}
内部静态uint计算器ECRC32(字符串str)
{
uint[]crcTable=Crc32.MakeCrcTable();
uint crc=0xFFFFFF;
对于(int i=0;i>8)^crcTable[(crc^c)&0xFF];
}
返回~crc;//(crc^(-1))>>0;
}
内部静态uint[]MakeCrcTable()
{
uint c;
uint[]crcTable=新uint[256];
对于(uint n=0;n<256;n++)
{
c=n;
对于(int k=0;k<8;k++)
{
var-res=c&1;
c=(res==1)?(0xEDB88320^(c>>1)):(c>>1);
}
crcTable[n]=c;
}
返回crcTable;
}

使用此代码
Console.WriteLine(Crc32.calculaterc32(“l”)按预期显示
2517025534

您确定链接了正确的问题吗?你链接的是一个字符代码,而不是JSCRC…你能不能调试这个来发现问题?转储CRC表并查看它是否匹配。在每次计算后转储CRC,并查看它们何时发散,等等。我们甚至没有您的参考实现来比较。。。谷歌还展示了许多c#实现,你可以将它们与之进行比较以找出问题所在。有一件事让我立即怀疑,你使用Int64计算CRC32是否正确?这个名字暗示了32位,这里的实现也是如此:是的,它就是这个类型。改为uint后,它就可以工作了。我忙着调试,没时间考虑类型。谢谢,没问题。我真的很喜欢调试挑战,因为它们很好,而且像这样是独立的