11

次のプロパティを持つPerl文字列チェックサム関数を探しています。

  • 入力:未定義の長さのUnicode文字列($string
  • 出力:符号なし整数($hash)、0 <= $hash <= 2^32-1保持(0〜4294967295、4バイトのMySQL unsigned intのサイズに一致)

擬似コード:

sub checksum {
    my $string = shift;
    my $hash;
    ... checksum logic goes here ...
    die unless ($hash >= 0);
    die unless ($hash <= 4_294_967_295);
    return $hash;
}

理想的には、チェックサム関数は実行が速く、衝突を回避するためにターゲット空間( 0.. )である程度均一に値を生成する必要があります。2^32-1このアプリケーションでは、ランダムな衝突は完全に致命的ではありませんが、可能な限り回避したいと思います。

これらの要件を考えると、これを解決するための最良の方法は何ですか?

4

3 に答える 3

14

任意のハッシュ関数で十分です。単純に 4 バイトに切り捨てて数値に変換します。優れたハッシュ関数にはランダムな分布があり、この分布は文字列をどこで切り詰めても一定です。

Digest::MD5をお勧めします。これは、Perl に標準で付属している最速のハッシュ実装であるためです。Pimが言及しているように、String::CRCもCで実装されており、より高速になるはずです。

ハッシュを計算して整数に変換する方法は次のとおりです。

use Digest::MD5 qw(md5);
my $str = substr( md5("String-to-hash"), 0, 4 );
print unpack('L', $str);  # Convert to 4-byte integer (long)
于 2009-12-22T14:05:47.420 に答える
5

差出人perldoc -f unpack

        For example, the following computes the same number as the
        System V sum program:

            $checksum = do {
                local $/;  # slurp!
                unpack("%32W*",<>) % 65535;
            };
于 2009-12-22T16:18:29.570 に答える
4

どれほど速いかはわかりませんが、String::CRCを試してみてください。

于 2009-12-22T13:04:03.303 に答える