FNV哈希算法
由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出。
特点和用途:FNV能快速hash大量数据并保持较小的冲突率,它的高度分散使它适用于hash一些非常相近的字符串,比如URL,hostname,文件名,text,IP地址等。
算法版本: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位的就够用了。
算法描述:
相关变量:
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-1a和FNV-1的唯一区别就是xor和multiply的顺序不同,他们所采用的FNV_prime和offset_basis都相同,有人认为FNV-1a在进行小数据(小于4个字节)哈希时有更好的性能。
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值的第八位做抑或运算。
FNV_prime的取值:
32 bit FNV_prime = 2^24 + 2^8 + 0x93 = 16777619
64 bit FNV_prime = 2^40 + 2^8 + 0xb3 = 1099511628211
128 bit FNV_prime = 2^88 + 2^8 + 0x3b = 309485009821345068724781371
256 bit FNV_prime = 2^168 + 2^8 + 0x63 =374144419156711147060143317175368453031918731002211
512 bit FNV_prime = 2^344 + 2^8 + 0x57 = 35835915874844867368919076489095108449946327955754392558399825615420669938882575
126094039892345713852759
1024 bit FNV_prime = 2^680 + 2^8 + 0x8d =
50164565101131186554345988110352789550307653454047907443030175238311120551081474
51509157692220295382716162651878526895249385292291816524375083746691371804094271
873160484737966720260389217684476157468082573
offset_basis的取值:
32 bit offset_basis = 2166136261
64 bit offset_basis = 14695981039346656037
128 bit offset_basis = 144066263297769815596495629667062367629
256 bit offset_basis = 100029257958052580907070968620625704837092796014241193945225284501741471925557
512 bit offset_basis = 96593031294966694980094354007163104660904187456726378961083743294344626579945829
32197716438449813051892206539805784495328239340083876191928701583869517785
1024 bit offset_basis = 14197795064947621068722070641403218320880622795441933960878474914617582723252296
73230371772215086409652120235554936562817466910857181476047101507614802975596980
40773201576924585630032153049571501574036444603635505054127112859663616102678680
82893823963790439336411086884584107735010676915
如果我想得到的哈希位数不是上面几种呢?
比如我想得到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)。简单吧!!
算法实现:
- //sheepdog中64位FNV-1a算法的实现
- /*
- * 64 bit FNV-1a non-zero initial basis
- */
- #define FNV1A_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
- /*
- * 64 bit Fowler/Noll/Vo FNV-1a hash code
- */
- // 调用时,hval的参数值为FNV1A_64_INT,即算法描述中的offset_basis
- static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
- {
- unsigned char *bp = (unsigned char *) buf;
- unsigned char *be = bp + len;
- while (bp < be) {
- hval ^= (uint64_t) *bp++;
- hval += (hval << 1) + (hval << 4) + (hval << 5) +
- (hval << 7) + (hval << 8) + (hval << 40);
- }
- return hval;
- }
FNV哈希算法的更多相关文章
- FNV哈希算法【转】
转自:http://blog.csdn.net/hustfoxy/article/details/23687239 由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn ...
- FNV哈希算法(转)
由来:FNV哈希算法全名为Fowler-Noll-Vo算法,是以三位发明人Glenn Fowler,Landon Curt Noll,Phong Vo的名字来命名的,最早在1991年提出. 特点和用途 ...
- 一致性哈希算法(consistent hashing)样例+測试。
一个简单的consistent hashing的样例,非常easy理解. 首先有一个设备类,定义了机器名和ip: public class Cache { public String name; pu ...
- .NET平台开源项目速览(12)哈希算法集合类库HashLib
.NET的System.Security.Cryptography命名空间本身是提供加密服务,散列函数,对称与非对称加密算法等功能.实际上,大部分情况下已经满足了需求,而且.NET实现的都是目前国际上 ...
- java单向加密算法小结(2)--MD5哈希算法
上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...
- [基础技能] 安全技术——哈希算法密码破解之彩虹表(Rainbow Table)学习
1.基础知识 刚刚学习过数字签名的相关知识,以及数字签名的伪造技术,而伪造数字签名归根结底就是密码破解的一个过程,然而直接破解的速度是非常缓慢的,所以有人想出一种办法,直接建立出一个数据文件,里面事先 ...
- 一致性哈希算法与Java实现
原文:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...
- 五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法 ...
- 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...
随机推荐
- 如何把IP转换成经纬度(Java版)
经常有这种需求,拥有用户的IP地址,想要在地图上显示用户的访问量.这个时候就需要用到经纬度...应为一般的地图插件都是基于经纬度的. 那么问题来了,如何把IP转换成经纬度? 百度API 最国产的方式, ...
- Java线程:线程状态的转换
Java线程:线程状态的转换 一.线程状态 线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新状态:线程对象已 ...
- C++生成二级制文件过程(预处理->编译->链接 )
转载请注明出处 Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果.VC什么都帮我们搞了,不了解其中过程也完全没问题. 转到linux下写c++,总觉得有点虚 ...
- windows下zookeeper伪集群搭建
下载 http://www.apache.org/dyn/closer.cgi/zookeeper/ 解压 D:\Java\soft\zookeeper-3.4.6 伪集群 1.在 \zookeepe ...
- hibernate(五)核心开发接口与对象的三种状态
本文链接:http://www.orlion.ml/37/ 一.Configuration 1.AnnotationConfiguration 2.进行配置信息的管理 3.configure()方法通 ...
- IO流-概览
一. 抽象类InputStream和OutputStream构成了了IO类的基础 因为面向字节流的对象不便于处理Unicode形式储存的信息,所以从抽象类Reader和Writer中继承出专门用于处理 ...
- Sort the Array
/* 思路: 找到单调下降串的起始位置[l, r] 如果左边 0...l-1中的最大值 > l...r中的最小值 或者 r+1...n中的最小值 < l...r中的最大值 都是不能实现排序 ...
- SQL*Loader之CASE4
CASE4 1. SQL脚本 [oracle@node3 ulcase]$ cat ulcase4.sql set termout off rem host write sys$output &quo ...
- 自制jQuery标签插件
在项目中需要一个添加标签的小插件,查看了一些已有插件后,发现很现成的高级插件,也有比较简单的插件.最后还是决定自己来写,这样能控制代码,以后与其他插件结合使用的时候能更好的把控.初步在IE6 7 8, ...
- angular项目总结——angular + browserify + gulp + bower + less 架构分享
一眨眼,快三个月没有写博客了.一直在为自己没有写博客而懊恼,忙过这段时间,好好总结一下. 新项目主要是自己一个人在写,先搭建了一个初步的架构,用了我并不熟悉的angular,这个过程中,慢慢也熟悉了a ...