HASH算法介紹
- Hash,通常翻譯作「散列」,也有直接音譯爲「哈希」的,就是把任意長度的輸入(又叫作預映射, pre-image),經過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,而不可能從散列值來惟一地肯定輸入值。
- 數學表述爲:h = H(M) ,其中H( )--單向散列函數,M--任意長度明文,h--固定長度散列值。
HASH算法的實際應用-加密
- 常見的哈希加密算法:MD5,SHA-1,SHA-2,SHA-256,SHA-X(系列)
- 1) 文件校驗:MD5 Hash算法的「數字指紋」特性,使它成爲目前應用最普遍的一種文件完整性校驗和(Checksum)算法,很多Unix系統有提供計算md5 checksum的命令;
- 2) 數字簽名:在這種簽名協議中,雙方必須事先協商好雙方都支持的Hash函數和簽名算法。簽名方先對該數據文件進行計算其散列值,而後再對很短的散列值結果--如Md5是16個字節,SHA1是20字節,用非對稱算法進行數字簽名操做。對方在驗證簽名時,也是先對該數據文件進行計算其散列值,而後再用非對稱算法驗證數字簽名; (實際是HASH+非對稱加密)
- 3) 鑑權協議:須要鑑權的一方,向將被鑑權的一方發送隨機串(「挑戰」),被鑑權方將該隨機串和本身的鑑權口令字一塊兒進行 Hash 運算後,返還鑑權方,鑑權方將收到的Hash值與在己端用該隨機串和對方的鑑權口令字進行 Hash 運算的結果相比較(「認證」),如相同,則可在統計上認爲對方擁有該口令字,即經過鑑權。(摘要)
- HASH加密算法與其餘加密算法的主要不一樣點是:哈希(Hash)算法是一種單向密碼體制,即只有 加密過程,沒有解密過程
HASH算法的實際應用-查找
- 常見的哈希查找算法:BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash等
- 1) 基本思想是:以數據對象的關鍵詞 key 爲自變量,經過一個肯定的函數關係 $h$ ,計算出對應的函數值 $h(key)$ ,把這個值解釋爲數據對象的存儲地址,並按此存放,即「$存儲位置=h(key)$」。
- Gdb下函數符號實際對應的是一個內存地址,映射大小爲32bit或64bit(即32位系統或64位系統)
FNV算法介紹
- FNV哈希算法全名爲Fowler-Noll-Vo算法,是以三位發明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字來命名的,最先在1991年提出
- 特色和用途:FNV能快速hash大量數據並保持較小的衝突率,它的高度分散使它適用於hash一些很是相近的字符串,好比URL,hostname,文件名,text,IP地址等。
- 適用範圍:比較適用於字符串比較短的哈希場景
FNV哈希算法有以下兩種,FNV-1a相比FNV-1,散列分佈更好。兩者不一樣點爲:for循環兩行代碼的順序相反html
哈希函數通常適用移位和乘除法來實現。哈希函數通常都比較精簡,算法複雜度比較低。哈希函數的移位和乘除法可能會致使數據丟失,這也是哈希不可逆的緣由算法
FNV算法說明-1
- hash值:一個n位的unsigned int型hash值,初始值爲offset_basis.
- offset_basis:初始的哈希值,該值在最先的版本中是0,爲了加強哈希的可靠性,後續修改成非0的值,經過以下算法獲取
參見《生成offset_basis.py》函數
FNV算法說明-2
octet_of_data:8位數據(即一個字節):即須要被哈希的字符串加密
FNV_prime:FNV用於散列的質數(質數在哈希算法中發揮着重要做用,在通常使用的哈希除留餘數法中: H(key) = key MOD p,p也要求是一個質數(質數也稱爲素數))spa
- 32 bit FNV_prime = 224 + 28 + 0x93 = 16777619
- 64 bit FNV_prime = 240 + 28 + 0xb3 = 1099511628211
- 128 bit FNV_prime = 288 + 28 + 0x3b = 309485009821345068724781371
- 256 bit FNV_prime = 2168 + 28 + 0x63 = 374144419156711147060143317175368453031918731002211
- 512 bit FNV_prime = 2344 + 28 + 0x57 = 35835915874844867368919076489095108449946327955754392558399825615420669938882575126094039892345713852759
FNV算法使用
- 支持將字符串哈希爲32/64/128/256/512/1024bit的數字
- 支持將字符串哈希爲任意bit的數字,好比11/33bit
- 支持將字符串哈希爲特定範圍的數字,好比[0,99999]
將字符串哈希爲32bit的數字
hash = offset_basis
for each octet_of_data to be hashed
hash = hash xor octet_of_data
hash = hash * FNV_prime
return hash
參見《生成32位哈希.py》.net
將字符串哈希爲特定範圍的數字
將字符串哈希爲[0,999]的數字
#define TRUE_HASH_SIZE ((u_int32_t)50000) /* range top plus 1 */
#define FNV_32_PRIME ((u_int32_t)16777619)
#define FNV1_32_INIT ((u_int32_t)2166136261)
#define MAX_32BIT ((u_int32_t)0xffffffff) /* largest 32 bit unsigned value */
#define RETRY_LEVEL ((MAX_32BIT / TRUE_HASH_SIZE) * TRUE_HASH_SIZE)
u_int32_t hash;
void *data;
size_t data_len;
hash = fnv_32_buf(data, data_len, FNV1_32_INIT);
while (hash >= RETRY_LEVEL) {
hash = (hash * FNV_32_PRIME) + FNV1_32_INIT;
}
hash %= TRUE_HASH_SIZE;
參見《生成任意範圍哈希.py》翻譯
代碼附件連接:https://files.cnblogs.com/files/charlieroro/FNV%E5%93%88%E5%B8%8C%E7%AE%97%E6%B3%95%E8%AE%B2%E8%A7%A3.rarcode
參考:http://www.isthe.com/chongo/tech/comp/fnv/index.html#lazy-modhtm