博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

FNV哈希算法

Posted on 2023-03-20 14:31  linFen  阅读(768)  评论(0编辑  收藏  举报

NV版本

  • 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循环两行代码的顺序相反

 

FNV哈希分为3个版本:fnv-0(已废弃),FNV-1,FNV-1a

算法实现

FNV-0算法公式

hash = 0
   for each byte_of_data to be hashed
   		hash = hash * FNV_prime
   		hash = hash ^ octet_of_data
return hash

FNV-1算法公式

hash = FNV_offset_basis
   for each byte_of_data to be hashed
   		hash = hash * FNV_prime
   		hash = hash ^ byte_of_data
return hash

FNV-1a算法公式

hash = FNV_offset_basis
   for each byte_of_data to be hashed
   		hash = hash ^ byte_of_data
   		hash = hash * FNV_prime
return hash

FNV公式参数说明

1. FNV_offset_basis

这个参数的值是固定的,根据不同的位数选择不同的值作为hash的首次填充值

位数十进制值
32 2166136261
64 14695981039346656037
128 144066263297769815596495629667062367629
256 100029257958052580907070968620625704837092796014241193945225284501741471925557
512 965930312949666949800943540071631046609041874567263789610837432943446265799458
2932197716438449813051892206539805784495328239340083876191928701583869517785
1024 1419779506494762106872207064140321832088062279544193396087847491461758272325
2296732303717722150864096521202355549365628174669108571814760471015076148029
7559698040773201576924585630032153049571501574036444603635505054127112859663
61610267868082893823963790439336411086884584107735010676915

2. FNV_prime

还没有看懂,不过这不影响我们实现通用32位,64位的FNV算法

位数十进制值
32 16777619
64 1099511628211
128 309485009821345068724781371
256 374144419156711147060143317175368453031918731002211
512 35835915874844867368919076489095108449946327955754392558399825615420669938882
575126094039892345713852759
1024 501645651011311865543459881103527895503076534540479074430301752383111205510814745
150915769222029538271616265187852689524938529229181652437508374669137180409427187
3160484737966720260389217684476157468082573

3. hash

hash后的最总结果

4. byte_of_data

8位无符号整数

5. hashed

要加密的数据,需要转换成byte_of_data[]然后循环^计算

 

 

hash = hash * FNV_prime,是包含取模运算的,具体看你采用多少位的哈希函数。例如,你用32为哈希,hash = hash * FNV_prime % (2的32次方);

hash = hash xor octet_of_data,意思是把当前取来的字节和当前的hash值的第八位做抑或运算。

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 =
35835915874844867368919076489095108449946327955754392558399825615420669938882575
126094039892345713852759


1024 bit FNV_prime = 2680 + 28 + 0x8d =
50164565101131186554345988110352789550307653454047907443030175238311120551081474
51509157692220295382716162651878526895249385292291816524375083746691371804094271
873160484737966720260389217684476157468082573

  以上这几个数都是质数(哈希的理论基石,质数分辨定理,我理解也不深),不用管为什么,用的时候照搬就是了。