传统搜索算法是基于比较的,而哈希搜索算法通过关键字的值来标记元素的位置。
哈希算法由两部分组成,首先是能够将查询关键字转换成表地址的哈希函数。理想情况是不同的关键字映射到不同的地址,但经常出现两个或者多个关键字对应同一表地址的情况,如果两个输入关键字的hash函数的值一样,则称这两个关键字是一个碰撞(Collision),处理这种关键字的过程就是哈希搜索算法的第二部分冲突调节。
哈希函数:
如果我们有一个长度为M的表,那么我们需要的是能把关键字转化成[0,M-1]范围内整数的函数,理想的哈希函数要易于计算并且近似为随机函数,随机是指每一个输入,相应的输出应在某种程度上是等概率的。最简单的哈希函数h(k)=k mod M 其中M最好是接近表长的素数,这样可以减少冲突的几率,实际运算中k的值会比较大,可以采取分段计算的办法,因为
(a mod M + b) mod M = (a+b) mod M。对于字符串一个简单的哈希算法
int hash(char *v, int M)
{
int h = 0,a = 127;
for(; *v != 0; v++)
h = (a*h + *v) % M;
return h;
}
/*
本程序采用霍纳算(Horner)法,7位ASCII码基数为128,这里采用127素数
*/
上面的算法中乘数是固定的,我们可以选择乘数为随机数的算法
字符串的通用哈希算法
int hashU(char *v,int M)
{ int h,a = 31415,b = 27183;
for(h = 0; *v != 0; v++,a = a*b % (M-1))
h = (a*h + *v) % M
return (h < 0) ? (h + M) : h;
}
//为了算法效率的问题采用了一种简单的伪随机数
通用算法显然还是要比前一种算法慢很多,一般而言,最快的算法是使M为2的幂且使用下面的散列函数
inline int hash(Key v, int M)
{return v & (M-1);}
下面来看看JDK中的哈希算法
String的哈希算法
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
在hashMap中
再哈希
private static int oldHash(int h) {
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
return h;
}
取下标
static int indexFor(int h, int length) {
return h & (length-1);
}
表长度都是2^t这样下标范围在0~2^t-1,将哈希值与2^t-1进行&操作就得到了该范围内的下标,注意2^t-1的最后t位上全都是1,这样才能让哈希值的最后t位都能发挥作用,最大限度进行随机。 表扩容时是在原有长度(默认从16开始)翻倍,这样最后t位上始终是1
利用哈希算法的还有
Rabin-Karp字符串匹配算法
假定字符集Σ ={0, 1, 2, ……, 9}, 每一个字符对应一个十进制数字
(一般情况, 假定每个字符是基数为d的表示法中的一个数字, d=|Σ|。)可以用一个长度为k的十进制数字来表示由k个连续字符组成的字符串.
因此,字符串"31415" 对应于十进制数31415
已知模式P[1..m],设p表示其相应十进制数地值,类似地, 对于给定的文本T[1..n]. 用
ts 表示长度为m的子字符串 T[s + 1 ‥ s + m]( s = 0, 1, . . . , n – m), ts = p 当且仅当 [s + 1 ‥ s + m] = P[1 ‥ m]; 因此s是有效位移当且仅当 ts = p.
可以用霍纳规则(Horner’s rule) 在Θ(m) 的时间内计算p的值
p = P[m] + 10 (P[m - 1] + 10(P[m - 2] + · · · + 10(P[2] + 10P[1]) )).
类似地,可以在Θ(m)时间内,根据T[1..m]计算出t0 的值。
如果能在总共Θ(n - m + 1) 时间内计算出所有的ts 的值,那么通过把p值与每个ts(有n-m+1个)进行比较,就能够在Θ(m) + Θ(n - m + 1)= Θ(n) 时间内求出所有有效位移。(计算出1个ts 就跟p比较,处理结果。)
为了在Θ(n - m) 时间内计算出剩余的值t1, t2, . . . , tn-m 可以在常数的时间内根据ts计算出ts+1,先看例子,假如m = 5,ts = 31415, 我们去掉高位数字T [s + 1] = 3,然后在加入一个低位数字T [s + 5 + 1](假设为2),得到:
ts+1 = 10(31415 - 10000 • 3) + 2 = 14152.
哈希算法在密码学中应用非常广泛
在这方面目前应用最为广泛的hash函数是SHA-1和MD5,他们哈希值大多是128位和更长
hash函数在现实生活中应用十分广泛。很多下载网站都提供下载文件的MD5码校验,可以用来判别文件是否完整。另外,比如在重要的数据库中,所有密码都是保存的MD5码,这样即使数据库的管理员也无法知道用户的原始密码(MD5理论上是不可逆的,但现在好像已经被破解了,可以制造一个MD5码相同的字符串),避免隐私泄露(很多人在不同地方都是用的同一个密码)
分享到:
相关推荐
哈希(Hash)信息查看器是一种实用工具,主要用于验证文件的完整性和一致性。在IT行业中,哈希值扮演着至关重要的角色,它是一种通过特定算法将任意大小的数据转化为固定长度输出的唯一标识符。这个输出通常称为哈希...
哈希表,又称散列表,是一种高效的数据存储和检索结构,它通过特定的函数(哈希函数)将数据映射到一个固定大小的数组中,从而实现快速查找。在这个问题中,我们需要设计一个哈希表来存储班级的人名,每个名字用汉语...
在IT领域,Hash值是一种广泛使用的数据校验方式,它能够为任何大小的文件生成一个固定长度的唯一标识,这个标识通常称为哈希值或散列值。Hash值查看及修改软件,如"Hash_1.0.4_0523.exe"和"HashModifier.exe",是...
C语言实现散列表(哈希Hash表)实例详解 散列表(哈希Hash表)是一种常用的数据结构,它可以快速地查找、插入和删除数据。在C语言中,实现散列表可以使用数组和链表等数据结构。本文将详细介绍C语言实现散列表...
哈希算法 Hash 哈希算法 Hash 是一种常用的数据加密技术,用于将任意长度的数据转换为固定长度的哈希值。哈希算法 Hash 的设计目的是为了实现数据的加密和身份验证。下面我们将对哈希算法 Hash 进行详细的介绍和...
标题中的“hash.rar_HASH算法_fpga hash_hash_zebra85v_哈希表Verilog”揭示了这个压缩包文件的主要内容,它涉及到哈希(Hash)算法在高速Field-Programmable Gate Array(FPGA)上的实现,以及与Zebra85v硬件平台和...
哈希表(Hash Table)的核心思想是通过哈希函数将数据的关键字(key)映射到一个固定大小的数组中,使得查找、插入和删除操作的时间复杂度可以接近O(1)。 哈希函数是链式哈希表中的关键部分,它的主要任务是将...
此外,还可以考虑扩展到其他哈希算法,如平均色彩哈希(Average Hash)、差分色彩哈希(Difference Hash)和结构相似性哈希(Structure Hash)。每种方法都有其特点和适用场景,选择合适的哈希算法对于优化图像检索...
哈希计算工具 `java-hash` 是一款基于Java编程语言实现的专门用于进行哈希值计算的软件。在软件开发和信息安全领域,哈希算法扮演着至关重要的角色,它能够将任意长度的数据转换为固定长度的输出,这个输出被称为...
哈希值计算工具,如标题所示的"Hash Calculator",是一种用于验证数据完整性和一致性的实用程序。在信息技术领域,哈希(Hash)是通过特定算法将任意长度的数据转化为固定长度输出的过程。这个过程通常不可逆,即从...
哈希映射(Hash Map),又称为哈希表,是一种数据结构,用于高效地存储和检索键值对。它基于哈希表的概念,利用哈希函数将键(Key)映射到一个固定大小的数组(桶)中的特定位置,以此实现快速访问。哈希表最大的...
哈希码(Hash Code)是一种在计算机科学中广泛使用的数据处理技术,主要应用于查找和存储。标题中的"hash code"指的是这种技术,特别是在Java中的`Hashtable`类中的应用。哈希函数是哈希码的核心,它能够将任意大小...
MD5-Hash哈希值计算工具 当前程序版本:1.8 更新介绍: 1.8版增加了停止按钮(取消当前计算进程),修复了文件大小判断出错的问题。 1.7版增加了保存哈希值验证结果到文本的功能,更换了程序图标。 1.6版改进了验证时...
哈希表(Hash Table)是一种数据结构,它通过哈希函数将关键字映射到数组的索引位置,以此实现快速的查找、插入和删除操作。在C语言中实现哈希表,我们需要理解哈希函数的设计、冲突解决策略以及动态扩容等核心概念...
哈希(Hash)算法在密码学中扮演着至关重要的角色,它是确保数据保密性和完整性的核心工具。哈希算法是一种单向函数,它将任意长度的输入(也称为预映像)转化为固定长度的输出,这个输出被称为哈希值或消息摘要。...
哈希值计算工具,如HashTools,是IT领域中一种重要的数据校验工具。它能够对文件内容进行精确的计算,生成一个固定长度的哈希值,这个值就像文件的数字指纹,对于验证文件的完整性和原始性至关重要。在本篇文章中,...
哈希表,也被称为Hash Map,是计算机科学中一种高效的数据结构,用于存储键值对。它通过一种称为哈希函数的过程将键映射到数组的特定位置,从而实现快速的查找、插入和删除操作。在哈希表中,查找时间通常接近常数...
通过`std::hash`模板类的特化或者`std::unordered_set/map`的`hash_function`成员函数进行设置。 - **等价关系**:对于`std::unordered_map`,键的等价关系默认由`==`运算符决定。如果需要自定义,可以提供一个比较...