C#中的CRC32故障
我试图在C#中实现我自己的CRC32函数。我在JS中看到了一个优雅的解决方案 所以我想到了这个: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
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后,它就可以工作了。我忙着调试,没时间考虑类型。谢谢,没问题。我真的很喜欢调试挑战,因为它们很好,而且像这样是独立的