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()功能?我试过xorand CRC32,但它们并不真正适合这项任务,因为它们返回重复的值。我想为每一行生成一个唯一的校验和。

编辑 哦,校验和应该以允许比较行的方式计算。我想获取不同行的两个校验和,并判断其中一个是否大于另一个、小于另一个或相等。有没有机会实现这样的目标?

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

谢谢你。

4

2 回答 2

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;
于 2012-04-23T13:38:50.887 回答
3

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

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

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

于 2012-04-23T13:38:16.680 回答