如何使用Perl的'摘要'模块来计算CRC?

时间:2013-03-20 13:30:00

标签: perl crc digest

我需要在Perl中实现CRC-32(带有自定义多项式)。我已经看到有一个名为Digest::CRC的模块可以做到这一点。但是,当我将结果与在线计算器进行比较时,我得不到相同的CRC代码。


我的多项式是“101101”(bin)或“2d”(hex)

我的数据是“1e5”


在线计算器为https://ghsi.de/CRC/index.php?Polynom=101101&Message=1e5。我从计算器得到的结果是“1010”(bin)或“A”(hex)。


这是我使用过的Perl代码(在某处找到了)


use strict;

use warnings;

use Digest::CRC;

my $string = 0x01e5;

my $ctx = Digest::CRC->new(type => "crc32", poly => 0x2D);

$ctx->add($string);

print "CRC for '$string' is 0x" . $ctx->hexdigest . "\n";

这是此Perl代码的输出:

'485'的CRC为0x9d0fec86


我很确定在线计算器是正确的。

我的Perl代码出了什么问题?

1 个答案:

答案 0 :(得分:4)

正如所说,您的程序计算字符串485的CRC(字节34 38 35),这是数字0x1E5的十进制字符串表示形式。同时,网站正在计算字节01 e5的CRC。我不知道你想要哪一个,如果有的话。

绝对正确的是,网站不计算任何类型的CRC32,因为它的结果不是32位长,似乎取决于您指定的多项式的大小。

此外,如果您使用Digest::CRC指定type => 'crc32',它将忽略所有其他参数,只需计算标准CRC32。

如果你想要一个多项式为0x2D的32位CRC,你可以尝试

my $ctx = Digest::CRC->new(width => 32, poly => 0x2D);

但是还需要定义一些其他的东西来指定CRC,包括(但不限于)位和字节顺序,初始值和结束xor值,并且没有办法告诉它是否会给你正确的校验和,没有看到完整的规范。

当然你有一个文件说的不仅仅是“CRC32,多项式0x2d”


<强>更新

  

如何使用Digest::CRC将数据视为十六进制字节而不是字符串?

  • Digest::CRC只处理字符串,您需要以这种方式打包数据。在这种情况下,您可能需要my $string = "\x01\xe5"
  

另外,什么是“结束xor值”?

  • end xor值只是一个XOR的位模式,结果是获得最终CRC的最后一步。
  

另外如果我理解正确,以下两种方法应该给出相同的结果:

my $ctx1 = Digest::CRC->new(type => "crc32");
my $rr1 = $ctx1->add(pack 'H*', '1e5')->hexdigest;
print "a1=$rr1=\n";

my $ctx2 = Digest::CRC->new(width => 32, poly => 0x04c11db7);
my $rr2 = $ctx2->add(pack 'H*', '1e5')->hexdigest;
print "a2=$rr2=\n";
  

但是我得到了不同的结果:

a1=fef37cd4= a2=758cce0=
  

你能告诉我我的错误在哪里吗?

  • 正如我所说,CRC有许多说明符。这就是为什么你必须建立你需要的CRC的完整规范,包括不仅仅是宽度和多项式。要显式生成CRC32校验和,您需要这个
my $ctx = Digest::CRC->new(width => 32, poly => 0x04c11db7, init => 0xFFFFFFFF, xorout => 0xFFFFFFFF, refin => 1, refout => 1);

这会应用0xFFFFFFFF的初始值和最终值,并将refinrefout设置为true。这会在处理之前和之后反转位顺序( ref reflect 的缩写),并且是MSB优先和LSB优先之间的差异。