我有一个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
,但它们并不适合这项任务,因为它们会返回重复的值。我想为每一行生成一个唯一校验和。
修改 哦,校验和应该以允许比较行的方式计算。我想取两个不同行的校验和,并判断其中一个是否大于另一个,小于另一个,或相等。是否有可能实现类似的目标?
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
谢谢。
答案 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;
对于需求的排序部分,您可能需要反转字节的顺序,具体取决于行数组的哪一端最重要。