2009-10-16 106 views
2

假設我想要計算一個數據結構的散列,使用像MD5這樣的接受串行流的散列算法來進行等價檢查。 (我想記錄散列,然後在相同或等效的數據結構上重新計算散列,並檢查散列以便以高概率測量等價。)計算數據結構的散列?

是否有標準方法來執行此操作?

問題我可以看到,是有問題的是

  • 如果該數據結構包含二進制字符串數組,我不能只將它們連接起來,因爲[「ABC」,「DEFG」]和[「AB 「,」cdefg「]不是等價的數組
  • 如果數據結構包含不保證以相同順序枚舉的集合,例如一個鍵值字典{a:「bc」,d:「efg」,h:「ijkl」},它應該被認爲等價於一個鍵值對{d:「efg」,h:「ijkl」,a: 「公元前」}。
+0

除非您使用的是函數式語言,否則還有像數組這樣的對象被用作鍵然後更改其值的問題。該對象是否仍然是有效的密鑰?在ruby中,例如Hash類有一個實例方法rehash(這裏是該類的實現:http://www.ruby-doc.org/doxygen/1.8.4/hash_8c-source.html) – 2009-10-16 17:42:24

回答

3

對於第一個問題,也散列字符串的長度。這將區分它們的哈希值。

對於第二個,對鍵進行排序。

1

結構還存在另一個問題,它是數據成員在不同平臺上的對齊。 如果你想要一個穩定和便攜的解決方案,你可以通過爲你的數據結構實現「序列化」方法來解決這個問題,以便序列化產生字節流(或者更常見的是輸出到字節流)。 然後,您可以使用序列化流的散列算法。以這種方式,您將能夠通過明確的數據轉換解決您提到的問題。作爲其他附加功能,您將能夠將數據保存到硬盤或通過網絡發送。

對於字符串,您可以實現長度最先的Pascal類型存儲。

1
  • 如果字符串不能有任何空字符,可以使用C字符串來保證唯一性,例如。 「abc \ 0defg \ 0」不同於「cdefg \ 0」。
  • 對於字典,也許你可以在散列之前進行排序。

這也讓我想起我聽說一旦一個問題......我不知道你用的是什麼語言,但如果你也散列C的結構沒有以任何方式過濾它們,小心對待出於對齊原因,編譯器可能引入的字段之間的空間。有時候這些不會被清除。

2

這樣做的「標準」方式是定義數據結構的序列化形式,並對結果字節流進行摘要。

例如,TBSCertificate是包含主題名稱,擴展名和其他信息的數據結構。這將以確定性方式轉換爲一串八位字節,並作爲數字簽名操作的一部分進行哈希處理以生成證書。