3

Perl で CRC-32 (カスタム多項式を使用) を実装する必要があります。Digest::CRCと呼ばれるモジュールがあることを確認しました。しかし、結果をオンライン計算機と比較すると、同じ CRC コードが得られません。


私の多項式は "101101" (ビン) または "2d" (16 進数) です

私のデータは「1e5」です


オンライン計算機はhttps://ghsi.de/CRC/index.php?Polynom=101101&Message=1e5です。計算機から得た結果は、「1010」(ビン) または「A」(16 進数) です。


これは私が使用した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 コードの何が問題になっていますか?

4

1 に答える 1

4

あなたのプログラムは、文字列485(バイト34 38 35) の CRC を計算しています。これは、数値の 10 進文字列表現です0x1E5。その間、Web サイトはバイトの CRC を計算しています01 e5。あなたが望むなら、どちらかはわかりません。

間違いなく正しいのは、Web サイトが 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を使用して、データを文字列ではなく 16 進バイトとして扱うにはどうすればよいですか?

  • Digest::CRC文字列のみを処理し、データをそのようにパックする必要があります。この場合、おそらく必要ですmy $string = "\x01\xe5"

また、「エンドxor値」とは何ですか?

  • 値は、end xor最終的な CRC を取得するための最後のステップとして、結果と XOR される単純なビット パターンです。

さらに、私があなたを正しく理解していれば、次の 2 つの方法で同じ結果が得られるはずです。

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

これにより、 and0xFFFFFFFFセットの初期値と最終値がtrue に適用されます。これは、処理前と処理後の両方でビット順序を逆にします ( refは、 reflectの略です)。これは、MSB ファーストと LSB ファーストの違いです。refinrefout

于 2013-03-20T15:30:58.300 に答える