C# 相当于Windows中的Unix cksum

C# 相当于Windows中的Unix cksum,c#,checksum,crc32,C#,Checksum,Crc32,我下载了一个文件和他的校验和(由cksum Unix命令生成) 所以,我想,在我的C#app测试中,校验和是否与我下载的应用程序相等 我查看了chsum的Unix手册页: 因此,我编写了一个简单的程序来计算: byte[] arr = File.ReadAllBytes(@"MyApp").ToArray(); int cksum = 0; foreach (byte x in arr) { cksum += (x ^ 32 + x ^ 26 + x ^ 23 + x ^ 22 +

我下载了一个文件和他的校验和(由cksum Unix命令生成)

所以,我想,在我的C#app测试中,校验和是否与我下载的应用程序相等

我查看了chsum的Unix手册页:

因此,我编写了一个简单的程序来计算:

byte[] arr = File.ReadAllBytes(@"MyApp").ToArray();

int cksum = 0;

foreach (byte x in arr)
{
    cksum += (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 + x ^ 0);
}
但是校验和是不一样的,我怎样才能解决这个问题呢

谢谢


编辑 1) 修改后的算法是:

uint cksum = 0;

foreach (byte b in arr)
{
    var x = (uint)b;

    cksum += (IntPow(x, 32)
        + IntPow(x, 26) + IntPow(x, 23) + IntPow(x, 22)
        + IntPow(x, 16) + IntPow(x, 12) + IntPow(x, 11) + IntPow(x, 10)
        + IntPow(x, 8) + IntPow(x, 7) + IntPow(x, 5) + IntPow(x, 4) + IntPow(x, 2) + IntPow(x, 1) + IntPow(x, 0));
}
2) 我使用了
类Crc32:HashAlgorithm

给定一个Unix文件,其中Crc32为:2774111254

  • 1) 给我:4243613712
  • 2) 给我:3143134679(种子为0)

我做错了什么

这些是异能,而不是异或。请参阅。

在c#^中,它不是幂运算符的提升,而是异或运算符,而CRC是使用通用的数学术语编写的,不特定于任何语言

也不要使用标准的“pow”函数,因为这些函数通常使用浮点来表示非常大的数字,例如x^32

而你想要的是保持答案的低32位。最好的解决方法可能是:

  • 编写您自己的整数幂函数,该函数将参数作为整数,并通过将x^N乘以x^N来计算x^N,并相信.NET运行时具有合理的效率(或者如果运行速度太慢,则使用一些优化方法,如通过平方进行幂运算)。不要让数字变得太大,或者在每次乘法后使用余数或按位and运算符进行四舍五入,或者使用未经检查的值并相信它们每次都会换位并保持低位32位
  • 查找直接计算CRC32的库或现有代码(例如)
在C#中,
^
符号是异或运算符。你想要这个功能

这给出了两个浮点数的幂,建议在

因此,您的代码看起来像:

cksum += Math.pow(x,32) + Math.pow(x,26)
还要注意最后一句话:

计算结果被截断为32位值。这个 还将打印文件中的字节数

这是有符号的(
int
)还是无符号的(
uint

当然,您可以使用以下选项:

另请参见此正确实现

有关crc32检查的C#实现,我尝试了链接提供的类,但没有相同的结果。Unix:
>cksum file2.exe
:2774111254<代码>Crc32.计算(arr):1514701405;之前的代码已更正为Pow:4243613712。它们有什么不同?
cksum += Math.pow(x,32) + Math.pow(x,26)