Hash哈希(一)
Hash哈希(一)
哈希是大家比较常见一个词语,在编程中也经常用到,但是大多数人都是知其然而不知其所以然,再加上这几天想写一个一致性哈希算法,突然想想对哈希也不是很清楚,所以,抽点时间总结下Hash知识。本文参考了很多博文,感谢大家的无私分享。
基本概念
Hash,一般翻译做“散列”,也有直接音译为“哈希”的。那么哈希函数的是什么样的?大概就是 value = hash(key),我们希望key和value之间是唯一的映射关系。
大家使用的最多的就是哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构,通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度,这个映射函数叫做哈希函数或散列函数。
实际中的Hash主要有两种应用:加密和压缩。在加密方面,Hash哈希是把一些不同长度的信息转化成杂乱的128位的编码,这些编码值叫做HASH值,最广泛应用的Hash算法有MD4、MD5、SHA1。在压缩方面,Hash哈希是指把一个大范围映射到一个小范围,往往是为了节省空间,使得数据容易保存。
Hash的特点
主要原理就是把大范围映射到小范围,因此输入范围必须和小范围相当或者比它更小,否则增加冲突。
Hash函数逼近单向函数,所以可以用来对数据进行加密。(单项函数:如果某个函数在给定输入的时候,很容易计算出其结果来;而当给定结果的时候,很难计算出输入来)
不同的应用对Hash函数有着不同的要求:用于加密的Hash函数主要考虑它和单项函数的差距,而用于查找的Hash函数主要考虑它映射到小范围的冲突率。
Hash算法
Hash的产生方式大体可以分为三种基本方法:加法、乘法和移位。
加法哈希是通过遍历数据中的元素然后每次对某个初始值进行加操作,其中加的值和这个数据的一个元素相关。
/********************************
*加法哈希
*@key 输入字符串
*@prime 素数
********************************/
int additiveHash(string key, int prime)
{
int hash, i;
for(hash = key.length(), i = ; i < key.length(); ++i)
{
hash += int(key.at(i));
}
return (hash%prime);
}
乘法哈希是通过遍历数据中的元素然后每次对初始值进行乘法操作,其中乘的值无需和数据有关系。
/********************************
*乘法哈希
*@key 输入字符串
*@prime 素数
********************************/
int bernstein(string key)
{
int hash, i;
for(hash = , i = ; i < key.length(); ++i)
{
hash = *hash + int(key.at(i));
}
return hash;
} /********************************
*32位FNV算法(乘法)
*@key 输入字符串
*@prime 素数
********************************/
int M_SHIFT = ;
int M_MASK = 0x8765fed1;
int FNVHash(string key)
{
int hash = (int)2166136261L;
for(int i = ; i < key.length(); ++i)
{
hash = (hash * )^int(key.at(i));
}
if(M_SHIFT == )
return hash;
return (hash ^ (hash >> M_SHIFT)) & M_MASK;
}
在JAVA中,哈希函数使用的就是乘法哈希:
/**
* JAVA自己带的算法
*/
public static int java(String str) {
int h = ;
int off = ;
int len = str.length();
for (int i = ; i < len; i++)
{
h = * h + str.charAt(off++);
}
return h;
}
移位哈希是通过遍历数据中的元素然后每次对初始值进行移位操作。
/********************************
*旋转哈希(移位)
*@key 输入字符串
*@prime 素数
********************************/
int rotatingHash(string key, int prime)
{
int hash, i;
for(hash = key.length(), i = ; i < key.length(); ++i)
{
hash = (hash << )^(hash >> )^int(key.at(i));
}
return (hash%prime);
}
实际情况下,很多哈希函数都是包含加法、乘法和移位操作来实现的,例如MD5。
问题
为什么prime的取值是素数? 有科学依据么? 有待验证
有人是这样说的取素数,可以降低碰撞的概率。但是并没有很好的说明原因,如果哪位有想法希望能留下您的想法,分享给大家。
Hash哈希(一)的更多相关文章
- redis:hash哈希类型的操作
1. hash哈希类型的操作 1.1. hset key field value 语法:hset key field value 作用:把key中field域的值设为value 注:如果没有field ...
- 第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型
第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型 Hash操作,redis中Hash在内存中的存储格式如下图: hset(name, key, value)name ...
- 上传图片用图片文件的对象hash哈希值判断图片是否一样,避免重复提交相同的图片到服务器中
上传图片用图片文件的对象hash哈希值判断图片是否一样,避免重复提交相同的图片到服务器中 前端:要用到一个插件,点击下载 <!DOCTYPE html> <html xmlns=&q ...
- hash 哈希查找复杂度为什么这么低?
hash 哈希查找复杂度为什么这么低? (2017-06-23 21:20:36) 转载▼ 分类: c from: 作者:jillzhang 出处:http://jillzhang.cnblogs ...
- Hash 哈希(上)
Hash 哈希(上) 目录 Hash 哈希(上) 简介 Hash函数的构造 取余法 乘积取整法 其他方法 冲突的处理 挂链法 开放定址法 线性探查法 二次探查法 双哈希法 结语 简介 Hash,又称散 ...
- Hash哈希类型
hash类型是使用得非常非常多的一种redis数据类型,相当于C#中的Dictionary和Hashtable. hset命令(语法:hset key field value)将哈希表key中的fie ...
- Hash哈希(二)一致性Hash(C++实现)
一致性Hash 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,经常用于分布式.负载均衡等. 原理 一致哈希是 ...
- Hash(哈希)
一.基本概念 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的 ...
- Redis[三] @Hash 哈希
Redis的哈希值是字符串字段和字符串值之间的映射,所以他们是表示对象的完美数据类型 在Redis中的哈希值,可存储超过400十亿键值对. redis 提供了2套操纵 一种是批量 一种是非批量 假设需 ...
随机推荐
- iOS响应者链和事件传递机制
原文来自:http://www.cnblogs.com/zhw511006/p/3517248.html 响应者链(Responder Chain) 通常,一个iOS应用中,在一块屏幕上通常有很多的U ...
- (转载)IOS中UIScrollView的属性和委托方法
http://www.jizhishusheng.com/?p=453 ---- 以下内容来自 UIScrollView 类负责所有基于 UIKit 的滚动操作一.创建 1. CGRect bou ...
- 【MVC】 基础
[MVC] 基础 一. Controller ActionResult ContentResult 返回string类型 EmptyResult 空 FileContentResult ...
- 如何用Jquery实现 ,比如点击图片之后 ,该图片变成向下的箭头,再点击向下箭头的图片 又变成原始图片呢
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>切换 ...
- UIScrollViewDelegate
一.执行顺序:(scrollView加后面的)willBeginDragging // 将要开始拖拽,手指已经放在view上并准备拖动的那一刻 DidScroll ...
- POJ 1873 - The Fortified Forest 凸包 + 搜索 模板
通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命.. 这题 N = 15 1 << 15 = 32768 直接枚举完全可行 卡在异常情况判断上很久,只有 顶点数 &g ...
- Java swing项目-图书管理系统(swing+mysql+jdbc)
(一)项目功能分析 该项目是设计一个图书管理系统,主要包含的内容有: (1)管理员登陆界面 ->信息录入 ->登录 ->重置 (2)图书管理系统总界面 ->子界面菜单: 1)图 ...
- ContentProvider 增删改查通讯录
一.通讯录应用介绍 通讯录应用是Android自带的应用程序,我们看到此应用的时候,可能只认为这是一个应用,用数据库存储数据,但是实际上不是这样的. 通讯录是ContentProvider的应用,通讯 ...
- [转] 在Linux平台使用mhVTL虚拟化磁带库
原文来自:LIUBINGLIN ---- http://blog.itpub.net/23135684/viewspace-1307626/ <在Linux平台安装mhVTL虚拟化磁带库> ...
- ABP的事件总线和领域事件(EventBus & Domain Events)
http://www.aspnetboilerplate.com/Pages/Documents/EventBus-Domain-Events EventBus EventBus是个单例,获得Even ...