哈希算法(Hash)
哈希算法也叫散列算法,一般來說滿足這樣的關系:Func(data)=key,輸入任意長度的 data,經過哈希算法處理后輸出一個定長的數據 key。同時這個過程是不可逆的,無法由 key 逆推出 data。
- MD5
- SHA:SHA-1,SHA-224, SHA-256,SHA-384,SHA-512
注意,哈希表(HashTable)是利用了哈希函數的一種數據結構
散列表(Hash table,也叫哈希表),是根據關鍵碼值 (key/value) 而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。給定表 M,存在函數 Func(key),對任意給定的關鍵字值 key,代入函數后若能得到包含該關鍵字的記錄在表中的地址,則稱表 M 為哈希表,函數 Func(key) 為哈希函數。
哈希表是一種通過哈希函數將特定的鍵映射到特定值的一種數據結構,他維護著 key 和 value 之間的一 一對應關系。
Hash List
在點對點網絡中作數據傳輸的時候,會同時從多個機器上下載數據,而且很多機器可以認為是不穩定或者不可信的。為了校驗數據的完整性,更好的辦法是把大的文件分割成小的數據塊(例如,把分割成 64KB 為單位的數據塊)。這樣的好處是,如果小塊數據在傳輸過程中損壞了,那么只要重新下載這一快數據就行了,不用重新下載整個文件。
怎么確定小的數據塊沒有損壞哪?只需要為每個數據塊做 Hash。BT下載的時候,在下載到真正數據之前,我們會先下載一個 Hash 列表。那么問題又來了,怎么確定這個Hash列表本事是正確的哪?答案是把每個小塊數據的Hash值拼到一起,然后對這個長字符串在作一次Hash運算,這樣就得到Hash列表的根Hash(Top Hash or Root Hash)。下載數據的時候,首先從可信的數據源得到正確的根Hash,就可以用它來校驗Hash列表了,然后通過校驗后的Hash列表校驗數據塊。
默克爾樹(Merkle Tree)
-
二叉樹:平衡二叉樹,非平衡二叉樹
在計算機科學中,二叉樹是每個節點最多有兩個子樹的樹結構,每個節點代表一條結構化數據。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。
二叉樹常被用于實現數據快速查詢。二叉樹如下圖所示:
默克爾樹
默克爾樹(Merkle tree)是一種哈希二叉樹,1979年由 Ralph Merkle 發明。
Merkle Tree可以看做Hash List的泛化(Hash List可以看作一種特殊的Merkle Tree,即樹高為2的多叉Merkle Tree)。
在最底層,和哈希列表一樣,我們把數據分成小的數據塊,有相應地哈希和它對應。但是往上走,并不是直接去運算根哈希,而是把相鄰的兩個哈希合并成一個字符串,然后運算這個字符串的哈希,這樣每兩個哈希就結婚生子,得到了一個”子哈希“。如果最底層的哈希總數是單數,那到最后必然出現一個單身哈希,這種情況就直接對它進行哈希運算,所以也能得到它的子哈希。于是往上推,依然是一樣的方式,可以得到數目更少的新一級哈希,最終必然形成一棵倒掛的樹,到了樹根的這個位置,這一代就剩下一個根哈希了,我們把它叫做 Merkle Root[3]。
在 P2P 網絡下載網絡之前,先從可信的源獲得文件的 Merkle Tree 樹根。一旦獲得了樹根,就可以從其他從不可信的源獲取 Merkle tree。通過可信的樹根來檢查接受到的Merkle Tree。如果 Merkle Tree 是損壞的或者虛假的,就從其他源獲得另一 個Merkle Tree,直到獲得一個與可信樹根匹配的 Merkle Tree。
Merkle Tree 和Hash List 的主要區別是,可以直接下載并立即驗證 Merkle Tree 的一個分支。因為可以將文件切分成小的數據塊,這樣如果有一塊數據損壞,僅僅重新下載這個數據塊就行了。如果文件非常大,那么 Merkle tree 和 Hash list 都很到,但是 Merkle tree 可以一次下載一個分支,然后立即驗證這個分支,如果分支驗證通過,就可以下載數據了。而Hash list只有下載整個hash list才能驗證。
典型應用
- 快速比較大量數據:當兩個默克爾樹根相同時,則意味著所代表的數據必然相同(哈希算法決定的)。
- 快速定位修改:例如上例中,如果 D1 中數據被修改,會影響到Hash0-0,Hash0 和 Root。因此,沿著 Root --> 0 --> 0-0,可以快速定位到發生改變的 D1;
- 零知識證明:例如如何證明某個數據(D0……D3)中包括給定內容 D0,很簡單,構造一個默克爾樹,公布 N0,N1,N4,Root,D0 擁有者可以很容易檢測 D0 存在,但不知道其它內容。
- 數據完整性校驗:git 版本控制系統,ZFS/IPFS 分布式文件系統以及 BT 下載,都是通過 Merkle Tree 來進行完整性校驗的。
-
在分布式存儲系統中的應用:
為了保持數據一致,分布系統間數據需要同步,如果對機器上所有數據都進行比對的話,數據傳輸量就會很大,從而造成“網絡擁擠”。為了解決這個問題,可以在每臺機器上構造一棵 Merkle Tree,這樣,在兩臺機器間進行數據比對時,從 Merkle Tree 的根節點開始進行比對,如果根節點一樣,則表示兩個副本目前是一致的,不再需要任何處理;如果不一樣,則沿著hash值不同的節點路徑查詢,很快就能定位到數據不一致的葉節點,只用把不一致的數據同步即可,這樣大大節省了比對時間以及數據的傳輸量。
相對于 Hash List,MT的明顯的一個好處是可以單獨拿出一個分支來(作為一個小樹)對部分數據進行校驗,這個很多使用場合就帶來了哈希列表所不能比擬的方便和高效。正是源于這些優點,MT常用于分布式系統或分布式存儲中。
more..
- Merkle Tree 在數字加密貨幣中首先應用于比特幣(BTC),以太坊(Etherum)采用了改進的 Merkle Patricia Tree (MPT) 。
默克爾證明(Merkle Proof)
- 比特幣錢包用 Merkle Tree 的機制來作 百分百準備金證明
- 比特幣SPV中 如何利用默克爾樹證明某個交易是否存在
- EOS.IO 通過默克爾證明 實現區塊鏈間通信