mysql fnv64函数_FNV哈希算法

FNV哈希函数,有三种FNV-0(已废弃),FNV-1, FNV-1a。

FNV-1和FNV-1a算法对于最终生成的哈希值(hash)有一定限制

1,hash是无符号整型

2,hash的位数(bits),应该是2的n次方(32,64,128,256,512,1024),一般32位的就够用了。

FNV-1形式:

hash=offset_basisforeach octet_of_data to be hashed hash=hash*FNV_prime hash=hash xor octet_of_datareturnhash

FNV-1a形式:

hash=offset_basisforeach octet_of_data to be hashed hash=hash xor octet_of_data hash=hash*FNV_primereturnhash

区别是有两句操作顺序调换,产生FNV-1a的原因是,有些人使用FNV-1a代替FNV-1发现算法离散性或CPU利用效率更好(我感觉应该没什么太大差距,只是微小的)。

for each octet_of_data to be hashed 意思是对于你要算哈希值的数,它的每一个字节。

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 = 1677761964 bit FNV_prime = 240 + 28 + 0xb3 = 1099511628211128 bit FNV_prime = 288 + 28 + 0x3b = 309485009821345068724781371256 bit FNV_prime = 2168 + 28 + 0x63 = 374144419156711147060143317175368453031918731002211512 bit FNV_prime = 2344 + 28 + 0x57 = 358359158748448673689190764890951084499463279557543925583998256154206699388825751260940398923457138527591024 bit FNV_prime = 2680 + 28 + 0x8d = 5016456510113118655434598811035278955030765345404790744303017523831112055108147451509157692220295382716162651878526895249385292291816524375083746691371804094271873160484737966720260389217684476157468082573

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

如果我想得到的哈希位数不是上面几种呢?

比如我想得到24位的哈希值,方法:取上面比24大的最小的位数,当然是32了,先算对应32位哈希值,再转换成24位的。

转换方法:32 - 24 = 8, 好了把得到的32砍成两段,高8位最和低24位。第8位与低24位中的低8位做抑或,得到的24位值是最终结果。(hash>>24) ^ (hash & 0xFFFFFF); 如果我想得到的哈希值不能用位数来表示呢?

比如想得到范围在0~9999的哈希值,方法:取上面比9999大的最小的位数,当然是32,先算对应32位哈希值,再mod(9999 +1)。简单吧!!

其实还有一种方法,可以避免上面方法出现的某些问题(映射分布有点儿不均匀,这个问题在一般情况下不用考虑,所以方法也不介绍了,有兴趣可以去网站上看看)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值