数组元素的校验和

时间:2012-04-23 13:21:32

标签: delphi multidimensional-array checksum

我有一个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()功能?我已经尝试了xorCRC32,但它们并不适合这项任务,因为它们会返回重复的值。我想为每一行生成一个唯一校验和。

修改 哦,校验和应该以允许比较行的方式计算。我想取两个不同行的校验和,并判断其中一个是否大于另一个,小于另一个,或相等。是否有可能实现类似的目标?

EDIT2 两个相邻行中的示例数据:

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

谢谢。

2 个答案:

答案 0 :(得分:6)

您的数据对我来说听起来不连贯。您定义了一个array[0..6] of byte,但在您的数据示例中,您有超出字节范围的值,即0..255,如444,323,1024 ......某处出现错误。

由于每行只包含7个字节的数据,因此最简单的方法是将其包装成Int64值。这不是一个crc,而只是一个类型转换。所以根据定义,你不会在这里发生任何碰撞 - 这是一个完美的哈希。

这是某种“穷人的哈希”,但这很容易。

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

我已将该函数定义为inline,因为它会更快。

对于阵列中的最后一个TRow,您将拥有一个字节重叠的内存访问权限,但它将按预期工作。为了避免这种情况,一个更慢但更安全的功能:

function HashOf(const Row: TRow): Int64;
begin
  result := 0;
  move(Row,result,sizeof(Row));
end;

答案 1 :(得分:3)

您需要将其存储在至少7个字节的位置,以获得所需的唯一性属性。因此,这表明UInt64。只需将TRow的7个字节复制到UInt64即可。

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

对于需求的排序部分,您可能需要反转字节的顺序,具体取决于行数组的哪一端最重要。