原文:https://blog.csdn.net/u013137970/article/details/79020095golang
FNV算法簡介
FNV算法屬於非密碼學哈希函數,它最初由Glenn Fowler和Kiem-Phong Vo於1991年在IEEE POSIX P1003.2上首先提出,最後由Landon Curt Noll 完善,故該算法以三人姓的首字母命名。算法
FNV算法目前有三種,分別是FNV-1,FNV-1a和FNV-0,可是FNV-0算法已經被丟棄了。FNV算法的哈希結果有3二、6四、12八、25六、512和1024位等長度。若是須要哈希結果長度不屬於以上任意一種,也能夠採用根據Changing the FNV hash size - xor-folding上面的指導進行變換獲得。bash
算法過程
FNV-1
FNV-1算法過程以下:函數
hash = offset_basis for each octet_of_data to be hashed hash = hash * FNV_prime hash = hash xor octet_of_data return hash
參數說明(以32位結果爲例,其它長度同理):工具
全部的參數,除了octet_of_data以外,都是32位無符號整型,即hash、offset_basis、FNV_prime類型都是32位無符號整型;
octet_of_data的類型是8位無符號整型;
32位的offset_basis值爲2166136261=0x811c9dc5,FNV_prime值爲2^24 + 2^8 + 0x93 = 16777619,其它參數能夠查看FNV的維基百科主頁;
算法循環的次數等於輸入的字節長度;
算法的相乘部分,由於hash類型是32位無符號整型,故相乘結果須要mod 2^32;
算法的異或部分,octet_of_data爲32位值的低8位,其它三個字節不進行異或運算。
舉例:網站
輸入「V」,對應的十六進制值爲0x56,輸出32位的FNV hash值爲0x050c5d49。能夠使用在線工具獲得結果。.net
計算過程:blog
初始化:hash = 2166136261
進入循環,由於要求的數據長度只有一個字節長度,故循環只有一次。由於hash結果爲32位無符號整型,故須要捨棄高位,保留低32位:hash = (2166136261 * 16777619) mod 2^32 = 0x050c5d1f
進行異或運算,首先將0x56轉化爲32位的值0x00000056,而後才能進行異或運算:hash = 0x050c5d1f xor 0x00000056 = 0x050c5d49
也能夠點擊參考資料中的FNV函數Go代碼更加深入地理解上述計算過程。ip
FNV-1a
FNV-1a算法過程以下:get
hash = offset_basis for each octet_of_data to be hashed hash = hash xor octet_of_data hash = hash * FNV_prime return hash
能夠發現,FNV-1a算法只是將相乘和異或運算進行了順序調換,其它過程和參數與FNV-1相同。
FNV-0
FNV-0算法過程以下:
hash = 0 for each octet_of_data to be hashed hash = hash * FNV_prime hash = hash XOR octet_of_data return hash
參考資料
FNV Hash:詳細介紹FNV算法的網站。在該網站上能夠找到該算法的歷史,應用以及源碼等資料。
Fowler–Noll–Vo hash function:FNV算法的維基百科主頁。
Source file src/hash/fnv/fnv.go:FNV函數的Go語言實現代碼,能夠更加深刻理解FNV算法過程。