想像你從網路下載了一部由上千個小分塊組成的大檔案,想確認「其中第 372 塊」沒被人偷偷改過——難道要把整份檔案重新算一次雜湊比對嗎? Merkle Tree(雜湊樹)給的答案是:不用。把每個資料區塊先各自算出一個雜湊(指紋),再兩兩往上合併, 最後收斂成單一的 root hash。這個 root 就像整份資料的「總指紋」:只要任何一塊被改動一個位元,沿途每一層的雜湊、直到 root 都會跟著變—— 這就是 git 的 commit、區塊鏈的交易、BitTorrent 分塊校驗背後共同的防篡改機制。
更妙的是驗證:要證明「某個區塊確實屬於這個 root」,你不需要整棵樹,只要那條路徑上每一層的兄弟雜湊—— 對 n 個區塊只需 O(log n) 個。這串兄弟雜湊就叫 Merkle proof(audit path)。下面這棵固定的 4 區塊小樹會依序帶你走三步: ① 建樹(葉子雜湊 → 逐層合併 → root)、② Merkle proof(用 2 個兄弟雜湊驗證某區塊屬於 root)、 ③ 篡改(改一個葉子,看它如何沿路把 root 整個掀翻)。
x=(x*31+code) mod 大質數,
再取低 16 位當 4 位 16 進位短碼顯示(方便在小圓圈裡看清楚)。它不是密碼學雜湊——真實的 git/區塊鏈用的是 SHA-256。
這裡示範的是 Merkle Tree 的結構性質(改一葉 → root 全變、proof 只需 O(log n) 兄弟),這些性質與雜湊的密碼學強度無關;
教學雜湊只是讓你把每一步的值看得一清二楚。資料區塊固定為 A B C D,播放軌跡決定性(每次重播完全一致)。
這棵樹用堆積式陣列索引表示(與 Min-Heap 同款):root 是索引 0、兩個內部節點是 1/2、四個葉子是 3~6,
節點 k 的左子固定為 2k+1、右子 2k+2、父為 (k-1)/2。建樹時,四個葉子先各自算 leafHash = H("L"+資料),
再由下而上把每對兄弟合併成 parentHash = H("B"+左+"-"+右),直到 root。
Merkle proof 對 data[1]="B" 示範:沿葉往上收集每一層的兄弟雜湊(本樹高 2,只需 2 個),
再用它們逐層重算,得到的值若等於原 root 就證明 B 確實屬於這個 root——全程不需碰其他子樹。
篡改則把 data[2] 從 "C" 改成 "X",你會看到葉子雜湊先變,接著沿「葉 → root」每個祖先被迫重算,root 最終從 2f5f 變成 2da6,
與原 root 不符即代表偵測到竄改。