以下是對該段 Verilog 代碼的逐步解釋,說明其如何實現 MurmurHash3 的壓縮邏輯:
h = key[63:32] ^ key[31:0];
- 操作:將 64-bit 輸入
key
拆分為高 32-bit 和低 32-bit,進行異或(XOR)。 - 目的:
- 消除輸入數據的局部性(如連續數值),確保高低位充分混合。
- 類似密碼學中的 Feistel 網絡結構,初步破壞數據模式。
h = (h ^ (h >> 16)) * 0x85EBCA6B;
- 步驟分解:
- 右移 16-bit:將
h
的高 16-bit 移至低 16-bit,高 16-bit 補零。
範例:若h = 0x12345678
→h >> 16 = 0x00001234
- 異或原值:
h ^ (h >> 16)
→ 混合高/低位信息,形成新的中間值。
範例:0x12345678 ^ 0x00001234 = 0x1234444C
- 魔數乘法:乘以常數
0x85EBCA6B
(質數,二進位形式有良好的擴散性)。- 乘法操作會導致低位與高位的非線性交互。
- 此常數經過精心選擇,確保雪崩效應(1-bit 變化導致多位變化)。
- 右移 16-bit:將
h = (h ^ (h >> 13)) * 0xC2B2AE35;
- 設計意圖:
- 使用不同位移量(13-bit)打破前一步的對稱性。
- 新魔數
0xC2B2AE35
進一步增強非線性,防止線性殘留。 - 此階段確保即使輸入有規律,輸出也能呈現偽隨機性。
murmur3_compress = h ^ (h >> 16);
- 終極混合:
- 將高位信息再次摺疊到低位,消除乘法可能引入的線性殘留。
- 最終異或操作類似熵壓縮,確保輸出 32-bit 的每一位都依賴於輸入的多個位。
每一輪操作形成一個 非線性函數鏈: [ h_{out} = f_{\text{non-linear}}(h_{in} \oplus (h_{in} \gg n)) ] 其中:
- ( \gg n ): 右移操作,擴散位模式
- ( \oplus ): 異或操作,破壞線性
- ( f_{\text{non-linear}} ): 魔數乘法引入的非線性變換
魔數 | 二進位特徵 | 作用 |
---|---|---|
0x85EBCA6B | 10000101111010111100101001101011 |
高漢明權重,確保乘法擴散性強 |
0xC2B2AE35 | 11000010101100101010111000110101 |
質數且位模式與前一常數互補,防碰撞 |
-
移位優先於旋轉:
使用右移而非位旋轉(Barrel Shifter),降低硬件實現複雜度。 -
定點乘法優化:
魔數選擇為 32-bit 質數,但 FPGA 可將其預編譯為常數乘法器,減少動態計算延遲。 -
流水線設計:
每級操作可劃分為獨立流水線階段,提升吞吐量。
- 輸入位寬:此實現壓縮 64-bit → 32-bit,而標準算法通常處理任意字節流。
- 輪次簡化:省略了最終的強混淆步驟(如
fmix32
),以適應硬件資源限制。 - 常數調整:魔數可能針對硬件友好性進行了修改。
通過這種級聯的非線性操作,代碼將任意 64-bit 輸入高效映射到 32-bit 空間,同時保持低碰撞率與高擴散性,適用於硬件加速的哈希表、布隆過濾器等場景。