读者指南:

参考资料 : 
https://blog.csdn.net/axuanwu/article/details/26060711
 

哈希和随机数的概念

哈希对信息计算得到一个位置信息,哈希不要求反向查找,哈希存在碰撞。
一个分布均匀的随机函数是一个良好的哈希算法。
素数乘法有很好的的随机性。 

哈希算法分类:

加法Hash;把输入元素一个一个的加起来构成最后的结果
位运算Hash;这类型Hash函数通过利用各种位运算(常见的是移位和异或)来充分的混合输入元素
乘法Hash;这种类型的Hash函数利用了乘法的不相关性(平方取中法,FNV算法)
除法Hash;除法和乘法一样,同样具有表面上看起来的不相关性。不过,因为除法太慢,这种方式几乎找不到真正的应用
查表Hash;查表Hash最有名的例子莫过于CRC系列算法。虽然CRC系列算法本身并不是查表,但是,查表是它的一种最快的实现方式。查表Hash中有名的例子有:Universal Hashing和Zobrist Hashing。他们的表格都是随机生成的。
混合Hash;混合Hash算法利用了以上各种方式。各种常见的Hash算法,比如MD5、Tiger都属于这个范围。它们一般很少在面向查找的Hash函数里面使用 
 

FNV算法

FNV-1和FNV-1a算法对于最终生成的哈希值(hash)有一定限制
  1,hash是无符号整型
  2,hash的位数(bits),应该是2的n次方(32,64),一般32位的就够用了。

 

相关变量:
hash值:一个n位的unsigned int型hash值
offset_basis:初始的哈希值
FNV_prime:FNV用于散列的质数
octet_of_data:8位数据(即一个字节)

 

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

 

FNV-1a描述:
hash = offset_basis
for each octet_of_data to be hashed
hash = hash xor octet_of_data
hash = hash * FNV_prime
return hash

 

FNV特点说明

FNV-1a和FNV-1的唯一区别就是xor和multiply的顺序不同,他们所采用的FNV_prime和offset_basis都相同,有人认为FNV-1a在进行小数据(小于4个字节)哈希时有更好的性能。

FNV_prime的取值:
32 bit FNV_prime = 2^24 + 2^8 + 0x93 = 16777619
64 bit FNV_prime = 2^40 + 2^8 + 0xb3 = 1099511628211

offset_basis的取值:
32 bit offset_basis = 2166136261
64 bit offset_basis = 14695981039346656037