3

Bytes次のように定義された多次元配列があります。

type
  TRow = array[0..6] of Byte;
var
  All: array[0..19112079] of TRow;  

ここで、配列を構成する各行の一意のチェックサムを生成し、次のようにファイルに保存したいと思います。

var
  I: Integer;
begin
  for I := 0 to 19112079 do
  begin
    Checksum := GenerateChecksum(All[I]);
    Writeln(F, Checksum);
  end;
end;

機能はどうすればいいGenerateChecksum()ですか?xorとを試しましCRC32たが、重複した値を返すため、このタスクにはあまり適していません。行ごとに一意のチェックサムを生成したいと思います。

EDIT ああ、行を比較できるようにチェックサムを計算する必要があります。異なる行の 2 つのチェックサムを取り、一方が他方よりも大きいか、他方よりも小さいか、または等しいかを判断したいと思います。そのような何かを達成するチャンスはありますか?

EDIT2 隣接する 2 行のデータ例:

Row x - 1: 120, 444, 323, 984, 1024, 76, 130
Row x:     120, 444, 323, 984, 1024, 76, 222
Row x + 1: 120, 444, 323, 984, 1024, 76, 121
. . .
Row x + n: 120, 444, 323, 984, 6333, 33, 935

ありがとうございました。

4

2 に答える 2

6

あなたのデータは私には一貫性がないように聞こえます。を定義しましたarray[0..6] of byteが、データの例では、444、323、1024 などの 0..255 などのバイト範囲外の値があります... どこかにエラーがあります。

各行には 7 バイトのデータしか含まれていないため、最も簡単な方法はそれをInt64値にラップすることです。これはcrcではなく、単なる型キャストです。したがって、定義上、ここでは衝突は発生しません。これは完全なハッシュです。

それはある種の「貧しい人のハッシュ」ですが、非常に簡単です。

function HashOf(const Row: TRow): Int64; inline;
begin
  result := PInt64(@Row)^ and $00ffffffffffffff;
end;

inlineより高速になるため、関数を次のように定義しました。

配列の最後のメモリ アクセスのオーバーラップが 1 バイトありますがTRow、期待どおりに動作します。これを回避するには、より遅いがより安全な関数:

function HashOf(const Row: TRow): Int64;
begin
  result := 0;
  move(Row,result,sizeof(Row));
end;
于 2012-04-23T13:38:50.887 に答える
3

必要な一意性を得るには、これを少なくとも 7 バイトに格納する必要があります。したがって、それは示唆してUInt64います。TRowa の 7 バイトを aにコピーするだけUInt64で完了です。

function PackRow(const Row: TRow): UInt64;
begin
  Result := 0;
  Move(Row, Result, SizeOf(Row));
end;

要件の順序付け部分については、行配列のどの端が最も重要であるかに応じて、バイトの順序を逆にする必要がある場合があります。

于 2012-04-23T13:38:16.680 に答える