2012-04-23 40 views
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()函數該怎麼辦?我試過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 

謝謝。

+0

只是爲了好奇,你用的是什麼版本的德爾福? – TLama 2012-04-23 13:27:52

+0

德爾福XE2更新3.我用'Writeln'來說明這個過程。 :) – Pateman 2012-04-23 13:28:19

+0

校驗和值(限制大小)從許多可能的數據中生成。它不可能是唯一的 – MajidTaheri 2012-04-23 19:59:59

回答

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; 
+0

+1或HashOf可能是var LHash:Int64絕對行;結果:= LHash; (: – ComputerSaysNo 2012-04-23 13:57:46

+1

@dorin什麼是字節8號?你最終會有垃圾在那裏。 – 2012-04-23 14:09:50

+0

@David是啊,錯過了那部分(: – ComputerSaysNo 2012-04-23 14:29:44

3

您需要將其存儲在至少7個字節的內容中才能獲得您所需的唯一性屬性。因此建議UInt64。只需將TRow的7個字節複製到UInt64即可完成。

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

對於您的需求的排序部分,您可能需要顛倒字節的順序,這取決於您的行數組的哪一端是最重要的。