相当于 Windows 中的 Unix cksum

发布于 2024-11-19 20:33:04 字数 1386 浏览 2 评论 0原文

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

因此,我想在我的 C# 应用程序测试中检查校验和是否与我下载的应用程序相符。

我查看了 chsum 的 Unix 手册页:

 cksum 命令计算校验和并将其打印到标准输出
  对于每个命名文件,文件中的八位字节数和
  文件名。

  cksum 使用基于 32 位循环冗余的可移植算法
  查看。该算法发现的错误范围比
  sum 使用的 16 位算法(请参阅 sum(1))。 CRC 是
  以下表达式,其中 x 是文件的每个字节。

       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

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

所以我写了一个简单的程序来计算总和:

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 的种子)

我做错了什么!?

I download a file and his checksum (generated by cksum Unix command).

So, I want, in my C# app test if the Checksum is in adequation with the app I downloaded.

I checked at the Unix man page of chsum:

  The cksum command calculates and prints to standard output a checksum
  for each named file, the number of octets in the file and the
  filename.

  cksum uses a portable algorithm based on a 32-bit Cyclic Redundancy
  Check.  This algorithm finds a broader spectrum of errors than the
  16-bit algorithms used by sum (see sum(1)).  The CRC is the sum of the
  following expressions, where x is each byte of the file.

       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

  The results of the calculation are truncated to a 32-bit value.  The
  number of bytes in the file is also printed.

So i wrote a simple program that does the sum :

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);
}

But checksums aren't the same, how can I fix this?

Thanks


EDIT

1) The modified algorithm is:

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) I used the class Crc32 : HashAlgorithm

Given an Unix file where the Crc32 is : 2774111254

  • 1) Gives me : 4243613712
  • 2) Gives me : 3143134679 (with a seed of 0)

What I'm doing wrong !?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

中性美 2024-11-26 20:33:05

在 C# 中,^ 符号是异或运算符。您需要函数 Math.Pow

这给出了两个浮点数的幂,在 How do你在 C# 中进行*整数*求幂?

所以,你的代码看起来像这样:

cksum += Math.pow(x,32) + Math.pow(x,26)

还要注意最后一条语句:

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

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

您当然可以使用以下内容:
http://www.codeproject.com/Articles/ 35134/如何用 C 语言计算 CRC

In C# the ^ symbol is the exclusive-or operator. You want the function Math.Pow.

This gives the piower of two floating point numbers, alteratives are suggested at How do you do *integer* exponentiation in C#?

So, your code would look something like:

cksum += Math.pow(x,32) + Math.pow(x,26)

Be aware also of the last statement:

The results of the calculation are truncated to a 32-bit value. The
number of bytes in the file is also printed.

Is this signed (int) or unsigned (uint)

you could of course use the following:
http://www.codeproject.com/Articles/35134/How-to-calculate-CRC-in-C

禾厶谷欠 2024-11-26 20:33:05

这些是权力,而不是异或。请参阅有关 CRC 的维基百科

Those are powers, not xors. See Wikipedia about CRC.

眼波传意 2024-11-26 20:33:05

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

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

而您想要的是保留答案的 32 位。可能最好的方法是:

  • 编写您自己的整数幂函数,该函数将参数作为 Ints 并通过执行 x N 次乘法来为您计算 x^N,并相信 .NET 运行时相当高效(或者如果它太高效)慢,使用一些优化,例如通过平方进行求幂)。不要让数字变得太大,可以在每个倍数之后使用余数或按位与运算符进行四舍五入,或者使用未经检查的值并相信它们每次都会回绕并保留低 32 位。
  • 查找直接计算 CRC32 的库或现有代码(例如 http: //www.google.co.uk/search?q=c%23+crc32)

In c# ^ is not a raise-to-the-power operator, but an xor operator, whereas the CRC is written using general mathsy terminology not specific to any language.

Don't use a standard "pow" function either since those will normally use floating point to represent very large numbers such as x^32.

Whereas what you want is to keep the low 32 bits of the answer. Probably the best way to is:

  • Write your own integer-power function, which takes arguments as Ints and calculates x^N for you by doing multiplication of x N times, and trusting the .NET runtime to be reasonably efficient (or if it's too slow, using some optimisation like doing exponentiation by squaring). Don't let the numbers grow too big, either by rounding off after each multiple using the remainder or bitwise-and operators, or using unchecked values and trusting them to wrap round and keep the low 32 bits each time.
  • Look for a library or existing code which calculates a CRC32 directly (eg. http://www.google.co.uk/search?q=c%23+crc32)
时光沙漏 2024-11-26 20:33:05

另请参阅此正确的实现 https://cksum.codeplex.com/

Also see this correct implementation https://cksum.codeplex.com/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文