I have a multidimensional array of Bytes
defined as follows:
type
TRow = array[0..6] of Byte;
var
All: array[0..19112079] of TRow;
Now, I would like to generate a unique checksum of each row the array consists of and save to a file, like so:
var
I: Integer;
begin
for I := 0 to 19112079 do
begin
Checksum := GenerateChecksum(All[I]);
Writeln(F, Checksum);
end;
end;
What should I do about the GenerateChecksum()
function? I've tried xor
and CRC32
, but they are not really suitable for this task, as they return duplicated values. I'd like to generate a unique checksum for each row.
EDIT Oh, the checksum should be computed in such way that it allows to compare rows. I would like to take two checksums of different rows and tell whether one of them is greater than the other, lesser than the other, or equal. Is there a chance of achieving something like that?
EDIT2 Example data in two adjacent rows:
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
Thank you.
Your data just sounds incoherent to me. You defined an array[0..6] of byte
, but in your example of data, you have values outside the byte range, i.e. 0..255, like 444, 323, 1024... There is an error somewhere.
Since each row only contains 7 bytes of data, the easiest is to wrap it into an Int64
value. This is not a crc, but just a typecast. So by definition, you won't have any collision here - this is a perfect hash.
It is some kind of "hash of the poor", but it would be very easy.
function HashOf(const Row: TRow): Int64; inline;
begin
result := PInt64(@Row)^ and $00ffffffffffffff;
end;
I've defined the function as inline
since it will be faster.
You'll have one byte overlapping of memory access for the last TRow
in your array, but it will work as expected. To avoid this, a slower but safer function:
function HashOf(const Row: TRow): Int64;
begin
result := 0;
move(Row,result,sizeof(Row));
end;