Hash 算法有哪些?
时间:2022-07-23
本文章向大家介绍Hash 算法有哪些?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Hash算法的有哪几种,优缺点,使用场景
Hash ,一般叫做散列算法,就是把任意长度的输入通过散列算法,变换成固定长度的输入,相当于一种压缩映射,将任意长度的消息压缩到某一固定长度的消息摘要的函数。
• 加法Hash;把输入元素一个一个的加起来构成最后的结果
/**
* 加法hash
*
* @param key
* 字符串
* @param prime
* 一个质数
* @return hash结果
*/
public static int additiveHash(String key, int prime) {
int hash, i;
for (hash = key.length(), i = 0; i < key.length(); i++)
hash += key.charAt(i);
return (hash % prime);
}
• 位运算Hash;这类型Hash函数通过利用各种位运算(常见的是移位和异或)来充分的混合输入元素
/**
* 旋转hash
*
* @param key
* 输入字符串
* @param prime
* 质数
* @return hash值
*/
public static int rotatingHash(String key, int prime) {
int hash, i;
for (hash = key.length(), i = 0; i < key.length(); ++i)
hash = (hash << 4) ^ (hash >> 28) ^ key.charAt(i);
return (hash % prime);
// return (hash ^ (hash>>10) ^ (hash>>20));
}
• 乘法Hash;这种类型的Hash函数利用了乘法的不相关性(乘法的这种性质,最有名的莫过于平方取头尾的随机数生成算法,虽然这种算法效果并不好);
static int bernstein(String key)
{
int hash = 0;
int i;
for (i=0; i<key.length(); ++i) hash = 33*hash + key.charAt(i);
return hash;
}
jdk5.0里面的String类的hashCode()方法也使用乘法Hash;32位FNV算法
int M_SHIFT = 0;
public int FNVHash(byte[] data) {
int hash = (int) 2166136261L;
for(byte b : data)
hash = (hash * 16777619) ^ b;
if(M_SHIFT == 0)
return hash;
return (hash ^ (hash >> M_SHIFT)) & M_MASK;
}
改进后的 FNV 算法
public static int FNVHash1(String data) {
final int p = 16777619;
int hash = (int) 2166136261L;
for (int i = 0; i < data.length(); i++)
hash = (hash ^ data.charAt(i)) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return hash;
}
常见的还有乘以一个不断改变的数
static int RSHash(String str) {
int b = 378551;
int a = 63689;
int hash = 0;
for (int i = 0; i < str.length(); i++) {
hash = hash * a + str.charAt(i);
a = a * b;
}
return (hash & 0x7FFFFFFF);
}
• 除法Hash;除法和乘法一样,同样具有表面上看起来的不相关性。不过,因为除法太慢,这种方式几乎找不到真正的应用
• 查表Hash;查表Hash最有名的例子莫过于CRC系列算法。虽然CRC系列算法本身并不是查表,但是,查表是它的一种最快的实现方式。查表Hash中有名的例子有:Universal Hashing和Zobrist Hashing。他们的表格都是随机生成的。
• 混合Hash;混合Hash算法利用了以上各种方式。各种常见的Hash算法,比如MD5、Tiger都属于这个范围。它们一般很少
- 数组 hash
inline int hashcode(const int *v)
{
int s = 0;
for(int i=0; i<k; i++)
s=((s<<2)+(v[i]>>4))^(v[i]<<10);
s = s % M;
s = s < 0 ? s + M : s;
return s;
}
在面向查找的Hash函数里面使用
环 hash
环 hash 计算步骤
- 首先求出哈希值, 并将其分配到 0~2^32 的圆上,其实把机器编号 hash 到这个环上。
- 采用同样的方法求出存储数据键的哈希值,并映射到相同的圆上
- 然后从数据映射到位置开始顺时针开始找,将数据保存到找到的第一个服务器,如果 2^32 仍然找不到服务器,就会保存到第一台服务器上。
image
环 hash 存在的问题
数据倾斜问题
数据倾斜是指,当机器不多时,几台机器在环上面贴的很近,分布是不是很均匀,会导致大部分数据集中到这几台机器上,这样就产生了数据倾斜问题。
如何解决数据倾斜问题?
引入了虚拟机器概念,一台机器需要在环上映射出多个这个位置,比如 我们用机器的 ip 来 hash ,这样就实现了一台物理机映射出多个虚拟机器的编号。
参考资料
- https://blog.csdn.net/l1028386804/article/details/54573106
- https://blog.csdn.net/wudiyong22/article/details/78687246
- RabbitMQ入门-高效的Work模式
- 谈谈分布式事务之四: 两种事务处理协议OleTx与WS-AT
- RabbitMQ入门-从HelloWorld开始
- RabbitMQ入门-从HelloWorld开始
- RabbitMQ入门-初识RabbitMQ
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
- 当InternalsVisibleToAttribute特性遭遇"强签名"
- MyBatis-从查询昨天的数据说起
- WCF并发(Concurrency)的本质:同一个服务实例上下文(InstanceContext)同时处理多个服务调用请求
- Spring集成RabbitMQ-必须知道的几个概念
- Spring读书笔记——bean创建(上)
- 15:21爆出的小程序功能升级,你还要对小程序观望吗?
- 如何解决分布式系统中的跨时区问题[原理篇]
- 什么是区块链:块的结构
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android实现WebView点击拦截跳转原生
- Android实现带节点的进度条
- Android WebView userAgent 设置为桌面UA实例
- Android WebView 内处理302重定向不跳转的解决
- android studio集成极光推送的操作步骤
- Android中的webview监听每次URL变化实例
- 解决Android WebView拦截url,视频播放加载失败的问题
- Android 极光推送别名与标签方式
- Android Webview的postUrl与loadUrl加载页面实例
- android Web跳转到app指定页面并传递参数实例
- Dialog全屏,去掉状态栏的方式
- Android 通过TCP协议上传指定目录文件的方法
- Android webview加载https链接错误或无响应的解决
- Android Manifest中meta-data扩展元素数据的配置与获取方式
- Android 配置gradle实现VersionCode自增实例