3哈希函数的构造方法
hash原理和实现方式
Hash原理和实现方式1. 介绍Hash(哈希)是一种将任意长度的输入数据转换为固定长度输出的算法。
该算法通过将输入数据映射到一个固定大小的哈希值来实现。
哈希函数通常用于数据完整性校验、密码学以及数据索引等领域。
本文将详细解释Hash的基本原理和实现方式,并介绍一些常见的Hash算法。
2. Hash函数基本原理Hash函数是Hash算法的核心组成部分,它接受任意长度的输入数据,并生成一个固定长度的哈希值。
2.1 确定性Hash函数应该是确定性的,即对于相同的输入数据,始终生成相同的哈希值。
这样可以保证在相同条件下产生相同结果,便于验证和比较。
2.2 均匀性理想情况下,Hash函数应该能够将不同的输入数据均匀地映射到不同的哈希值上。
这样可以最大程度地避免冲突,提高哈希表等数据结构的效率。
2.3 不可逆性Hash函数应该是不可逆的,即从哈希值无法推导出原始输入数据。
这样可以保护敏感信息和密码等重要数据的安全。
2.4 固定长度Hash函数应该生成固定长度的哈希值,无论输入数据的长度如何。
这样可以方便存储和比较哈希值。
3. Hash算法实现方式Hash算法有多种实现方式,下面介绍几种常见的实现方式。
3.1 分组Hash算法分组Hash算法将输入数据分成多个固定大小的块,然后对每个块进行处理,并生成最终的哈希值。
3.1.1 MD5(Message Digest Algorithm 5)MD5是一种广泛使用的分组Hash算法,它接受任意长度的输入数据,并生成一个128位(16字节)的哈希值。
MD5主要用于数据完整性校验和密码存储等领域。
然而,由于其安全性较低和易受到碰撞攻击,已经不再推荐使用。
3.1.2 SHA-1(Secure Hash Algorithm 1)SHA-1是一种与MD5类似的分组Hash算法,它接受任意长度的输入数据,并生成一个160位(20字节)的哈希值。
SHA-1在密码学领域中仍然广泛使用,但也存在安全性问题。
蜂考数据结构答案
蜂考数据结构答案1.什么是数据结构?数据结构是计算机存储、组织数据的方式。
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。
结构包括逻辑结构和物理结构。
数据的逻辑结构包括4种(1)集合:数据元素之间除了有相同的数据类型再没有其他的关系(2)线性结构:数据元素之间是一对一的关系——线性表、栈、队列(3)树形结构:数据元素之间是一对多的关系(4)图状结构:数据元素之间是多对多的关系。
物理结构包括顺序存储结构和链式存储结构。
2.解释一下顺序存储与链式存储顺序存储结构是用一段连续的存储空间来存储数据元素,可以进行随机访问,访问效率较高。
链式存储结构是用任意的存储空间来存储数据元素,不可以进行随机访问,访问效率较低。
3.头指针和头结点的区别?头指针:是指向第一个节点存储位置的指针,具有标识作用,头指针是链表的必要元素,无论链表是否为空,头指针都存在。
头结点:是放在第一个元素节点之前,便于在第一个元素节点之前进行插入和删除的操作,头结点不是链表的必须元素,可有可无,头结点的数据域也可以不存储任何信息。
4.线性结构的特点(1)集合中必存在唯一的一个"第一个元素";(2)集合中必存在唯一的一个"最后的元素";(3)除最后元素之外,其它数据元素均有唯一的"后继";(4)除第一元素之外,其它数据元素均有唯一的"前驱"。
5.数组和链表的区别?从逻辑结构来看:数组的存储长度是固定的,它不能适应数据动态增减的情况。
链表能够动态分配存储空间以适应数据动态增减的情况,并且易于进行插入和删除操作。
从访问方式来看:数组在内存中是一片连续的存储空间,可以通过数组下标对数组进行随机访问,访问效率较高。
链表是链式存储结构,存储空间不是必须连续的,可以是任意的,访问必须从前往后依次进行,访问效率较数组来说比较低。
如果从第i个位置插入多个元素,对于数组来说每一次插入都需要往后移动元素,每一次的时间复杂度都是O(n),而单链表来说只需要在第一次寻找i的位置时时间复杂度为O(n),其余的插入和删除操作时间复杂度均为O(1),提高了插入和删除的效率。
第七章-哈希表
哈希表又称散列表,实际上就是一个数组。
哈希函数是一个用来求存储在哈希的关键字在哈希表的地址下标的函数.比如一个哈希表int hashtable[5];现在有下面4个数要存入到哈希表中:(3,15,22,24)给定一个哈希函数: H(k)=k % 5最终数据存储如下图:理想情况下,哈希函数在关键字和地址之间建立了一个一一对应关系,从而使得查找只需一次计算即可完成。
由于关键字值的某种随机性,使得这种一一对应关系难以发现或构造。
因而可能会出现不同的关键字对应一个存储地址。
即k1≠k2,但H(k1)=H(k2),这种现象称为冲突。
把这种具有不同关键字值而具有相同哈希地址的对象称“同义词”。
在大多数情况下,冲突是不能完全避免的。
这是因为所有可能的关键字的集合可能比较大,而对应的地址数则可能比较少。
对于哈希技术,主要研究两个问题:(1)如何设计哈希函数以使冲突尽可能少地发生。
(2)发生冲突后如何解决。
哈希函数的构造方法:构造好的哈希函数的方法,应能使冲突尽可能地少,因而应具有较好的随机性。
这样可使一组关键字的散列地址均匀地分布在整个地址空间。
根据关键字的结构和分布的不同,可构造出许多不同的哈希函数。
1.直接定址法直接定址法是以关键字k本身或关键字加上某个数值常量c作为哈希地址的方法。
该哈希函数H(k)为:H(k)=k+c (c≥0)这种哈希函数计算简单,并且不可能有冲突发生。
当关键字的分布基本连续时,可使用直接定址法的哈希函数。
否则,若关键字分布不连续将造成内存单元的大量浪费。
2.除留余数法(注意:这种方法常用)取关键字k除以哈希表长度m所得余数作为哈希函数地址的方法。
即:H(k)=k %m这是一种较简单、也是较常见的构造方法。
这种方法的关键是选择好哈希表的长度m 。
使得数据集合中的每一个关键字通过该函数转化后映射到哈希表的任意地址上的概率相等。
理论研究表明,在m 取值为素数(质数)时,冲突可能性相对较少。
第21讲 哈希表(1)
构造好的哈希函数
好的哈希函数(均匀的哈希函数):哈希地 址均匀分布在整个地址空间,冲突次数少。
第九章 查找
构造哈希函数的方法
对数字 数字的关键字可有下列构造方法: 数字 1. 直接定址法 2. 数字分析法 3. 平方取中法 4. 折叠法 5. 除留余数法 6. 随机数法
239 385 878 +) 4 1 1543 239 583 878 +) 1 4 1714
叠 加
H(key) = 543
H(key) = 714
第九章 查找
习题:有一关键字为key = 347256198, 若表长为1000,请使用移位叠加法和 间界叠加法计算哈希地址。
分组: 347 256 198 移 位 叠 加
347 256 198 801
间
743 256 891 890
界 叠 加
H(key) = 801
H(key) = 890
第九章 查找
5. 除留余数法
设定哈希函数为: 设定哈希函数为 H(key) = key MOD p 其中 其中,p≤m (表长) 表长) p应为不大于 m 的素数 并且 应为不大于 或是 不含 20 以下的质因子 可以保证哈希地址在有效的地址空间之内。 可以保证哈希地址在有效的地址空间之内。
第九章 查找
哈希函数的好坏,必须结合查找表的情况来分析 好哈希函数的特点: ①计算效率高; ②函数值不越界; ③函数值的分布均匀。 一般的哈希函数设计方法 多开辟空间,以减少冲突。 装填因子=表中记录数 / 表长度 一般而言,装填因子越大,冲突可能性大。
第九章 查找
三、处理冲突的方法 处理冲突的方法 “处理冲突 的实际含义是: 处理冲突” 处理冲突
9.3 哈希表
9.3.3、处理冲突的方法法 1. 开放定址法
为产生冲突的地址 H(key) 求下一个哈希地址,如果该地址还 冲突,则再给出下一个地址,由此得到一个地址序列:
H0, H1, H2, …, Hs 1≤ s≤m-1
其中:H0 = H(key)
Hi = ( H(key) + di ) MOD m i=1, 2, …, s
1
3
条件:表长 m 应为形如 4j+3 的素数
(如: 7, 11, 19, 23, … 等)
Hi = ( H(key) + di ) MOD m, i=1, 2, …, s 3) 随机探测再散列
di 是一组伪随机数列 或者
di=i×H2(key) (又称双散列函数探测)
例如: 关键字集合
{ 19, 01, 23, 14, 55, 68, 11, 82, 36 }
ADT HashTable is
Data
HashTable;
Operations
initiate()
初始化Hash表
hash(key) Hash函数
search(key) 查找key
insert(key) 插入key
delete(key) 删除key
reCreate(size) 重建Hash表, 新表空间大于旧表, 旧表中的元素按新表的Hash函数插入新表中
设定哈希函数 H(key) = key MOD 11 ( 表长=11 )
6/28/2020
1 直接定址法 取关键字或关键字的某个线性函数作哈希地址,
即H(key)=key 或 H(key)=a·key+b(a,b为常数) 特点:直接定址法所得地址集合与关键字集合大小
数据结构 第4章
例子
假设要建立一个地址区间长度为13的哈希表,哈希函数为 H(key) = Ord(关键字第一个字母)-1)/2 其中函数Ord求字母在字母表中的序号。例如,字母A在 字母表中的序号为1, Ord(‘A’)=1。 现将关键字依次为Zhao, Qian, Sun, Li, Wu, Chen, Han的 7 个记录插入该哈希表。
例子
例如构造一个数据元素个数n = 60,哈希地址空间长度m = 100 的哈希表。 对关键字分析发现,关键字的第 1、2、3、6位取值比较集中,不 宜作为哈希地址,
…… 8 8 8 8 8 8 8 8 1 1 2 1 2 2 1 1 3 3 7 3 7 7 3 3 1 2 3 4 0 7 8 7 6 9 3 6 4 1 6 8 6 6 8 6 2 0 7 2 3 1 3 6 2 5 8 4 5 8 2
数据结构
广东工业大学 计算机学院
第4章 哈希表
第4章 哈希表
4.1 哈希表的概念 4.2 哈希函数的构造方法
4.2.1 直接定址法 4.2.2 除留余数法 4.2.3 数字分析法 4.2.4 折叠法 4.2.5 平方取中法 4.3.1 开放定址法 4.3.2 链地址法 链地址哈希表的实现 开放定址哈希表的实现
移位叠加 0040 1108 1053 0216 + 9891 (1)2308
Z形叠加 0040 8011 1053 6120 + 9891 (2)5115
4.2.5 平方取中法
平方取中法先取关键字的平方,然后根据哈希表地址区 间长度m的大小,选取平方数的中间若干位作为哈希地 址。通过取平方扩大关键字之间的差别,而平方值的中 间若干位和这个数的每一位都相关,使得不同关键字的 哈希函数值分布较为均匀,不易产生冲突。 设哈希表地址区间长度为1000,可取关键字平方值的中 间三位。
几种常见的哈希函数(散列函数)构造方法
几种常见的哈希函数(散列函数)构造方法哈希函数(散列函数)是一种将数据映射到固定长度的哈希值的函数。
它广泛应用于密码学、数据结构和网络安全等领域。
在设计哈希函数时,我们希望它能够将不同的输入映射到尽可能均匀的输出空间中,同时尽量避免冲突和哈希碰撞。
下面介绍几种常见的哈希函数构造方法。
第一种是除留余数法。
它是一种简单的哈希函数,将输入除以一些数并取余数作为哈希值。
这种方法简单快捷,适用于输入数据分布均匀的情况。
但是当输入数据分布不均匀时,容易导致冲突。
第二种是乘法哈希法。
这种方法将输入乘以一个常数,再取结果的小数部分或整数部分作为哈希值。
这种方法能够在一定程度上消除冲突,并且适用于输入数据分布不均匀的情况。
第三种是平方取中法。
该方法先将输入的平方,然后取中间的几位作为哈希值。
这种方法能够较好地消除冲突,但在数据集比较大的情况下,可能会增加计算的复杂度。
第四种是位运算法。
这种方法通常用于处理整数数据。
它将输入的整数进行移位、异或、与、或等位运算,最后得到哈希值。
这种方法在处理整数数据时效果比较好,但对于其他类型的数据可能不太适用。
第五种是分组法。
这种方法将输入数据分为若干个组,对每个组分别应用其他的哈希函数,最后合并得到哈希值。
这种方法可以很好地处理大规模数据,并且能够在一定程度上消除冲突。
第六种是加法哈希法。
该方法将输入的每个字符转化为对应的ASCII 码,然后将这些ASCII码值相加并取余数作为哈希值。
这种方法非常简单,但会导致冲突较多。
除了以上几种常见的哈希函数构造方法外,还有一些其他的方法,比如,有序统计量法、折叠法、循环冗余校验(CRC)等。
不同的哈希函数有不同的优缺点,我们可以根据具体的应用场景选择适合的哈希函数。
此外,为了提高哈希函数的性能,还可以使用哈希函数加速技术,如布谷鸟哈希等。
数据结构 第9章 查找4-哈希表
7、随机数法 Hash(key) = random ( key ) (random为伪随机函数)
适用于:关键字长度不等的情况。造表和查找都很方便。
小结:构造哈希函数的原则:
① ② ③ ④ ⑤ 执行速度(即计算哈希函数所需时间); 关键字的长度; 哈希表的大小; 关键字的分布情况; 查找频率。
三、冲突处理方法
14 H(14)=14%7=0
6个元素用7个 地址应该足够!
1
2
23 9
3
4
39 25 11
5
6
H(25)=25%7=4 H(11)=11%7=4
有冲突!
在哈希查找方法中,冲突是不可能避免的,只能 尽可能减少。
所以,哈希方法必须解决以下两个问题:
1)构造好的哈希函数
(a)所选函数尽可能简单,以便提高转换速度; (b)所选函数对关键码计算出的地址,应在哈希地址集中 大致均匀分布,以减少空间浪费。
讨论:如何进行散列查找?
根据存储时用到的散列函数H(k)表达式,迅即可查到结果! 例如,查找key=9,则访问H(9)=9号地址,若内容为9则成功; 若查不到,应当设法返回一个特殊值,例如空指针或空记录。
缺点:空间效率低!
若干术语
哈希方法 (杂凑法)
选取某个函数,依该函数按关键字计算元素的存储位置, 并按此存放;查找时,由同一个函数对给定值k计算地址, 将k与地址单元中元素关键码进行比较,确定查找是否成 功。
3. 乘余取整法
4. 数字分析法
5. 平方取中法
常用的哈希函数构造方法有:
6. 折叠法
7. 随机数法
1、直接定址法
(a、b为常数) 优点:以关键码key的某个线性函数值为哈希地址, 不会产生冲突. 缺点:要占用连续地址空间,空间效率低。
哈希函数的构造方法
哈希函数的构造⽅法哈希函数的构造⽅法本⽂阐述了哈希函数的构造⽅法有很多,但应注意两个原则:第⼀,函数值应在1⾄记录总数之间;第⼆,尽可能避免冲突。
设要存放的数据元素有n个,存放数据元素的内存单元有m个,设计哈希函数的⽬标就是要使通过哈希函数得到的n个数据元素的哈希地址尽可能均匀地分布在m个连续内存单元上,同时使计算过程尽可能简单以达到尽可能⾼的时间效率。
引⾔构造哈希函数的⽅法很多。
如何构造⼀个“好”的哈希函数是很强的技术性和实践性问题,这⾥的“好”指的是哈希函数构造⽐较简单,并且⽤此哈希函数产⽣的映射所发⽣的冲突可能性最⼩,换句话说⼀个好的哈希函数能将给定数据集合均匀地映射到给定的地址区间中。
Hash的原意是“弄乱,切碎”,这⾥的含义是“杂凑”。
基本做法是,根据集合元素值的分布情况,设计⼀个哈希函数h(ki),存储之素ki时,计算ki的哈希函数值,元素ki存储在a(h)中。
如果“幸运”,所设计的哈希函数很均匀,即任何ki≠kj,都有h(ki)≠h(kj),那么在查找ki时(再计算ki的哈希函数函数值h),就能在a[h]中找到元素ki。
1.直接定址法直接定址法是以数据元素关键字k本⾝或它的线性函数作为它的哈希地址,即:H(k)=k 或 H(k)=a×k+b ; (其中a,b为常数)例1,有⼀个⼈⼝统计表,记录了从1岁到100岁的⼈⼝数⽬,其中年龄作为关键字,哈希函数取关键字本⾝,如图(1):地址A1A2……A99A100年龄12 (99100)⼈数980800 (495107)可以看到,当需要查找某⼀年龄的⼈数时,直接查找相应的项即可。
如查找99岁的⽼⼈数,则直接读出第99项即可。
这种哈希函数简单,并且对于不同的关键字不会产⽣冲突,但可以看出这是⼀种较为特殊的哈希函数,实际⽣活中,关键字的元素很少是连续的。
⽤该⽅法产⽣的哈希表会造成空间⼤量的浪费,因此这种⽅法适应性并不强。
[2]↑2.数字分析法2.1数字分析法是取数据元素关键字中某些取值较均匀的数字位作为哈希地址的⽅法。
哈-希-技-术
• ● 除余法 该方法是最为简单常用的一种方法。它是以
表长m来除关键字,取其余数作为哈希地址,即 h(key)=key%m • 该方法的关键是选取m。选取的m应使得哈希函 数值尽可能与关键字的各位相关。m最好为素数。
【例】若选m是关键字的基数的幂次,则就 等于是选择关键字的最后若干位数字作为地址, 而与高位无关。于是高位不同而低位相同的关键 字均互为同义词。
常用哈希函数的构造方法
• ● 平方取中法
具体方法:先通过求关键字的平方值扩大相近数的差别,然 后根据表长度取中间的几位数作为哈希函数值。又因为一个乘 积的中间几位数和乘数的每一位都相关,所以由此产生的哈希 地址较为均匀。
【例】将一组关键字(0100,0110,1010,1001, 0111)平方后得
• 3) 哈希碰撞
• 从上述例子可见,不同的查找键值对应 HASH 函数的值相同是一 个普遍现象。在哈希组织中,每个桶的空间是固定的,如果某个桶 内已装满记录,还有新的记录要插入到该桶,那么称这种现象为桶 溢出 ( 也称为哈希碰撞 )。产生桶溢出的原因主要有两个:其一, 初始设计时桶数偏少; 其二,哈希函数的 " 均匀分布性 " 差,造成 某些桶存满了记录,而某些桶有较多空闲空间。
• 在文件中检索查找键值为 Ki 的记录,首先也是 计算 H(Ki), 求出该记录的桶地址,然后在桶内 查找。在哈希方法中,由于不同查找键值的记录 可能对应于同一个桶号,因此一个桶内记录的查 找键值可能是不相同的。因此,在桶内查找记录 时必须检查查找键值是否为所需的值。
• 在哈希文件中进行删除操作时,一般先用前述方 法找到欲删记录,然后直接从桶内删去即可。
• 最常使用的 HASH 函数是 " 质数求余法 "。其基本思想是: 首先确定所需存储单元数 M, 给出一个接近 M 的质数 P;再根 据转换的键号K, 代入公式 H(K)=K -INT(K/P)×P中,以求 得数据作为存储地址,一般 0H(K)P-1。
哈希函数构造方法及其适用情况
哈希函数构造方法及其适用情况【摘要】哈希表由于其效率的优越性应用范围非常广泛,而哈希表的效率由哈希函数决定。
哈希函数的构造方法有很多种,本文介绍了几种常用的构造方法,并分析了这几种方法的优劣及适用范围。
【关键词】哈希函数;直接定址法;数字分析法;平方取中法0.引言查找的效率取决于查找过程中必要的比较次数,比较次数越多查找效率就越低,反之,则越高。
理想的查找方法是无需比较,一次存取便能找到所查的记录。
这就要求记录的关键字和它的存储位置有确定的对应关系,使每个关键字和唯一的存储位置相对应,这样在查找时就可以根据这个对应关系,找出给定关键字记录的存储位置。
我们把这种对应关系称为哈希函数,由哈希函数得到的存储地址称为哈希地址,采用这种存储方式的存储结构称为哈希表。
哈希函数的构造方法有很多种,下文将逐一探讨。
1.直接定址法取关键字为哈希地址或者取关键字的某个线性函数值为哈希地址。
获得地址的公式为:address=a*key+b;其中a和b为常数,当a=1,b=0时,address=key。
例如有一个表存放了解放后每年的新生儿数量,关键字是年份,哈希函数为address=key+(-1948)。
这样,如果要查2000年的新生儿数,则只需要查第52(address=2000-1948)项数据即可。
采用直接定址法要求地址集合和关键字集合的大小相同,这样对不同的关键字不会发生冲突,但要求能确定关键字的取值范围,且取值范围不能太大,因此实际应用中能使用直接定址法的情况很少。
3.数字分析法如果哈希表中的关键字都是数字而且是事先知道的,则可以取关键字的若干位数字组成哈希地址,这种方法叫做数字分析法。
假设有100个记录,其关键字为6位整数,哈希表长度为200。
可以对全体关键字进行分析,如果发现第1、2、3、4位的数字是近似随机的,就可以取其中任意三位作为哈希地址,也可以取2组三位数进行叠加求和后舍去进位作为哈希地址。
4.平方取中法通常在选定哈希函数时不一定能知道关键字的全部情况,无法确定取其中哪几位合适,这时可以取关键字平方后的中间几位为哈希地址。
详解数据结构之散列(哈希)表
详解数据结构之散列(哈希)表1.散列表查找步骤散列表,最有用的基本数据结构之一。
是根据关键码的值直接进行访问的数据结构,散列表的实现常常叫做散列(hasing)。
散列是一种用于以常数平均时间执行插入、删除和查找的技术,下面我们来看一下散列过程。
我们的整个散列过程主要分为两步:1.通过散列函数计算记录的散列地址,并按此散列地址存储该记录。
就好比麻辣鱼,我们就让它在川菜区,糖醋鱼,我们就让它在鲁菜区。
但是我们需要注意的是,无论什么记录我们都需要用同一个散列函数计算地址,然后再存储。
2.当我们查找时,我们通过同样的散列函数计算记录的散列地址,按此散列地址访问该记录。
因为我们存和取的时候用的都是一个散列函数,因此结果肯定相同。
刚才我们在散列过程中提到了散列函数,那么散列函数是什么呢?我们假设某个函数为f,使得存储位置= f (key) ,那样我们就能通过查找关键字不需要比较就可获得需要的记录的存储位置。
这种存储技术被称为散列技术。
散列技术是在通过记录的存储位置和它的关键字之间建立一个确定的对应关系 f ,使得每个关键字key 都对应一个存储位置f(key)。
见下图这里的 f 就是我们所说的散列函数(哈希)函数。
我们利用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间就是我们本文的主人公------散列(哈希)上图为我们描述了用散列函数将关键字映射到散列表。
但是大家有没有考虑到这种情况,那就是将关键字映射到同一个槽中的情况,即f(k4) = f(k3) 时。
这种情况我们将其称之为冲突,k3 和k4 则被称之为散列函数 f 的同义词,如果产生这种情况,则会让我们查找错误。
幸运的是我们能找到有效的方法解决冲突。
首先我们可以对哈希函数下手,我们可以精心设计哈希函数,让其尽可能少的产生冲突,所以我们创建哈希函数时应遵循以下规则:1.必须是一致的。
假设你输入辣子鸡丁时得到的是在看,那么每次输入辣子鸡丁时,得到的也必须为在看。
sha3 算法填充方法
sha3 算法填充方法
SHA-3算法是一种密码散列函数,它是由美国国家标准技术研究所(NIST)在2015年发布的。
SHA-3算法的填充方法与其他哈希算法的填充方法略有不同。
在SHA-3算法中,填充方法是通过在消息的末尾添加特定的比特序列来实现的。
具体来说,SHA-3算法中的填充方法是使用了所谓的“sponge construction”(海绵构造)来完成的。
在这种构造中,消息被分割成固定长度的块,然后每个块被处理以生成哈希值。
在对消息进行填充时,会在消息的末尾添加一个特定的比特序列,该序列取决于消息的长度和SHA-3算法所使用的哈希函数。
填充方法的目的是确保消息的长度能够被正确地处理,并且不会影响最终的哈希值。
在SHA-3算法中,填充方法的设计是经过严格考虑的,以确保算法的安全性和性能。
总的来说,SHA-3算法的填充方法是通过在消息的末尾添加特定的比特序列来实现的,以确保消息的长度能够被正确地处理,并且不会影响最终的哈希值。
这种填充方法是为了满足算法的安全性和性能而精心设计的。
第九章哈希表
对增量 di 有三种取法:
• 1) • 2) • 3) • 线 平 随 性 方 机 探 探 探 测 测 测 再 再 再 散 散 散 列 列 列 di = c× i 最简单的情况 c=1 di = 12, -12, 22, -22, …, di 是一组伪随机数列 或者 伪随机数列 di=i×H2(key) (又称双散列函数探测 又称双散列函数探测) 又称双散列函数探测
二、构造哈希函数的方法 构造哈希函数的方法
对数字 数字的关键字可有下列构造方法: 数字
1. 直接定址法 2. 数字分析法 3. 平方取中法
4. 折叠法 5. 除留余数法 6. 随机数法
若是非数字关键字 非数字关键字,则需先 需先对其进行 进行 非数字关键字 需先 数字化处理。 数字化处理
1. 直接定址法
注意: 应具有“完备性” 注意:增量 di 应具有“完备性”
即:产生的 Hi 均不相同,且所产生的 s(m-1)个 Hi 值能覆盖 覆盖哈希表中所有 个 覆盖 地址。则要求: ※ 平方探测时的表长 m 必为形如 4j+3 的素数(如: 7, 11, 19, 23, … 等); ※ 随机探测时的 m 和 di 没有公因子。
示例: 示例: 有一个关键码 key = 962148,散列表大小 , m = 25,即 HT[25]。取质数 p= 23。散列函数 , 。 。 hash ( key ) = key % p。则散列地址为 。
hash ( 962148 ) = 962148 % 23 = 12。 12。
6.随机数法 随机数法
例如:为每年招收的 1000 名新生建立
一张查找表,其关键字为学号,其值的 范围为 xx000 ~ xx999 (前两位为年份)。 若以下标为 以下标为000 ~ 999 的顺序表 的顺序表表示之。 以下标为 则查找过程可以简单进行:取给定值 (学号)的后三位,不需要经过比较 不需要经过比较便 不需要经过比较 可直接从顺序表中找到待查关键字。
天大《数据结构》学习笔记六
这就是“冲突”。 (a)设计一个“好的”哈希函数:“好的”标准:(I)计算简便。(II)冲突少。 (b)给出解决冲突的方法。
5.3 构造哈希函数的方法举例:
构造哈希函数时应考虑到实际问题的需要,即表的长度,和键值的范围。如表长为 M,则 0<=h(k)<M. (1)除留余数法: 已知表长为 M,令 P 为接近 M 的质数,a 为常数(表头地址),则造 h(k)=k MOD p +a. 如:键值的范围为 000001 到 859999,M=6000 表头地址为 1000000,选 P=5987。 H(k)=k MOD 5987+1000000 如 k=179148 则 h(k)=1005525 (2)移位法: 如键值 k=32834872, M=1000
}
三、索引顺序查找(分块查找):
索引表:
本块最大 起始:
22
48
86
1
7
13
[1]
[7][13]来自22 12 13 8 9 20 33 42 44 38 24 48 60 58 74 49 86 53
块内无序,但块间有序:
数据结构—学习笔记六
查找方法:
(I)先决定在哪一块内(在索引表内) (II)再从此块内查找。
六、键树 如键集为:{CAI,CAO,LI,LAN,CHA……} 6.1 存入如下:
将此树转换为二叉树: 查某键时,按每个字母去查。此字母与二叉树上的当前行字母不匹配,则横向移动, 查下一;如匹配,则竖向移动,查下一个。 6.2 算法:(K.ch[num-1]为结束符$) { p=t->first; I=0;
328 348 + 72 748
数据结构—学习笔记六
哈希表的构造方法、冲突处理方法及哈希拉链法的简单代码实现
哈希表的构造⽅法、冲突处理⽅法及哈希拉链法的简单代码实现 由于哈希表的查找⾼效性,在平时的算法中⽤的也是⽐较多。
例如:字符串、单词个数的统计,只出现⼀次字符或者数字的统计,两个集合相同元素的查找等等,还有插⼊删除的⾼效(链地址法)都可以⽤哈希表来解决。
所以这⾥对其做⼀个⼩⼩的总结。
缺点可能是需要占⽤额外的内存空间。
⼀、哈希函数的构造⽅法下⾯介绍五种常⽤的哈希构造⽅法:构造哈希函数的原则是:(1)函数本⾝便于计算;(2)计算出来的地址分布均匀,即对任⼀关键字k,f(k) 对应不同地址的概率相等,⽬的是尽可能减少冲突。
1、除留余数法;取关键字被某个不⼤于哈希表长m的数p除后所得的余数为哈希地址。
即:H(key)=key MODE p,p<=m.(p的取值最好为素数)。
若冲突较多,可取较⼤的m和p值。
2、随机法;采⽤⼀个伪随机函数做哈希函数,即:H(key)=random(key)。
其中random为随机函数。
通常,当关键字长度不等时采⽤此法构造哈希函数较为恰当。
3、平⽅取中法;当⽆法确定关键字中哪⼏位分布较均匀时,可以先求出关键字的平⽅值,然后按需要取平⽅值的中间⼏位作为哈希地址。
这是因为:平⽅后中间⼏位和关键字中每⼀位都相关,故不同关键字会以较⾼的概率产⽣不同的哈希地址。
例如对于关键key:123。
1234^2=1522756,H(k)关键字的哈希地址为:227.4、折叠法;这种⽅法是按哈希表地址位数将关键字分成位数相等的⼏部分(最后⼀部分可以较短),然后将这⼏部分相加,舍弃最⾼进位后的结果就是该关键字的哈希地址。
具体⽅法有折叠法与移位法。
移位法是将分割后的每部分低位对齐相加,折叠法是从⼀端向另⼀端沿分割界来回折叠(奇数段为正序,偶数段为倒序),然后将各段相加。
例如:key=12360324711202065,哈希表长度为1000,则应把关键字分成3位⼀段,在此舍去最低的两位65,分别进⾏移位叠加和折叠叠加,求得哈希地址为105和907。
哈 希 常 见 算 法 及 原 理
java hash算法实现原理分布式Hash应用图片缓存到三台服务器上,Hash决定分到哪台服务器一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。
这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。
但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同。
两个不同的输入值,根据同一散列函数计算出的散列值相同的现象叫做碰撞。
常见的Hash函数有以下几个:直接定址法:直接以关键字k或者k加上某个常数(k+c)作为哈希地址。
数字分析法:提取关键字中取值比较均匀的数字作为哈希地址。
除留余数法:用关键字k除以某个不大于哈希表长度m的数p,将所得余数作为哈希表地址。
分段叠加法:按照哈希表地址位数将关键字分成位数相等的几部分,其中最后一部分可以比较短。
然后将这几部分相加,舍弃最高进位后的结果就是该关键字的哈希地址。
平方取中法:如果关键字各个部分分布都不均匀的话,可以先求出它的平方值,然后按照需求取中间的几位作为哈希地址。
伪随机数法:采用一个伪随机数当作哈希函数。
上面介绍过碰撞。
衡量一个哈希函数的好坏的重要指标就是发生碰撞的概率以及发生碰撞的解决方案。
任何哈希函数基本都无法彻底避免碰撞,常见的解决碰撞的方法有以下几种:开放定址法开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入。
链地址法将哈希表的每个单元作为链表的头结点,所有哈希地址为i的元素构成一个同义词链表。
即发生冲突时就把该关键字链在以该单元为头结点的链表的尾部。
再哈希法当哈希地址发生冲突用其他的函数计算另一个哈希函数地址,直到冲突不再产生为止。
以下 ()是常用的哈希函数构造方法
常用的哈希函数构造方法有以下几种:
1.直接定址法。
取关键字或关键字的某个线性函数值为哈希地址。
即:H (key)=key或
H (key)=a \cdot key+b。
其中a和b为常数(这种哈希函数叫做自身函数)。
2.相乘取整法。
将关键字与一个常数相乘,然后取整数部分作为哈希地址。
即:H (key)= (key) * a % p。
其中p是质数,a是小于p的常数。
3.平方取中法。
将关键字平方后取中间的几位作为哈希地址。
即:H (key)= key^2 % 10000 。
4.除留余数法。
将关键字除以一个常数,然后取余数作为哈希地址。
即:H (key)= key % p 。
5.伪随机数法。
利用伪随机数生成器生成一个随机数作为哈希地址。
6.数字分析法。
根据关键字中每个数字出现的频率来生成哈希地址。
7.分段折叠法。
将关键字分成若干段,每段用一种方法生成哈希地址,然后将这些地址拼接起来形成一个综合的哈希地址。
Java集合(八)哈希表及哈希函数的实现方式
Java集合(⼋)哈希表及哈希函数的实现⽅式Java集合(⼋)哈希表及哈希函数的实现⽅式⼀、哈希表⾮哈希表的特点:关键字在表中的位置和它之间不存在⼀个确定的关系,查找的过程为给定值⼀次和各个关键字进⾏⽐较,查找的效率取决于和给定值进⾏⽐较的次数。
哈希表的特点:关键字在表中位置和它之间存在⼀种确定的关系。
哈希函数:⼀般情况下,需要在关键字与它在表中的存储位置之间建⽴⼀个函数关系,以f(key)作为关键字为key的记录在表中的位置,通常称这个函数f(key)为哈希函数。
哈希(hash) : 翻译为“散列”,就是把任意长度的输⼊,通过hash算法,变成固定长度的输出,该输出就是hash值。
这种转换是⼀种压缩映射,hash值的空间通常远⼩于输⼊的空间,不同的输⼊可能会散列成相同的输出,所以不可能从hash值来唯⼀的确定输⼊值。
简单的说就是⼀种将任意长度的消息压缩到固定长度的消息摘要的函数。
实现哈希函数⼀般有6种⽅式:直接定址法、数字分析法、平⽅取中法、折叠法、除留余数法、随机函数法。
其中最常⽤的是除留余数法。
⼆、直接定址法取关键码的某个线性函数值作为哈希地址。
公式:H(k) = a × k + c (其中a,c为常数)。
优点:以关键码k的某个线性函数值为哈希地址,不会产⽣冲突。
缺点:会占⽤连续的地址空间,空间效率低。
当向字典中加⼊某⼀新元素时算法⾃动调⽤此函数,以确定该元素最终的存储位置。
若某元素关键码key为1,上式中,a=2,b=3则该元素最终会存储在字典第5个位置中。
例⼦:关键码集合为{100,200,500,700,900},选取哈希⽅法为:H(k) = k / 100,则哈希表(存储结构)如下:直接定址法的优点是实现⽅法简单,算法时间复杂度较⼩,⽽且不会产⽣冲突。
但是,直接定址法要求散列地址空间的⼤⼩与关键码集合的⼤⼩⼀致,⽽这种要求是苛刻的,⼀般很难实现。
例如当关键码的范围为1~1000000时,元素散列地址的个数也要达到1000000。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
6.1.哈希函数
当我们对长的文件使用DSS签名时,需要把文 件切成160 位的块并逐块分别签名,最后拼接起 来构成整个文件的签名。这样做存在问题是:
文件的签名太长. 使用安全性好的签名算法,计算签名的时间花费
太多. 将所有签名段的重新排序或删除其中一些段,最 后仍然.
例如: x x1 x2 xk , f ( x) xi 满足基本要求但不 i 1 满足单向性3)。 p, q 是大素数, n p q ,不满足1) g ( x) x 2 modn , 和4)5)。
为什么要提出性质3)4)和5)呢? 如果哈希函数不满足3),则对手有可能用特定签 名方案伪造随机消息摘要z 上的签名。例如对手 掌握随机消息摘要z 上的签名y,他可以找到消息 x 使 z h( x) ,则 ( x, y ) 就是合格的伪造品。为此 我们希望哈希函数满足单向性质。
6.1.1哈希函数的性质 哈希函数应满足的要求是: h( x) 固定长; 1) 压缩—— x 任意长, 2) 容易从 x 计算出 h( x) 。 3) 单向性(one-way)——基本上对所有事先指定的 y R ,找到 x 使 h( x) y 在计算上是困难的; 4) 弱抗碰撞(Weak Collision Resistance) ——已知 x ,找 x x 使 h( x) h( x) 在计算上是困难的; 5) 强抗碰撞(Strong Collision Resistance)——找任 两个不同的输入 x x ,使 h( x) h( x) 在计算上 是困难的. 其中1)2)是对哈希函数的基本要求。
以下两点提供了简单有效的构造方法。
1)任何强抗碰撞的压缩函数都可以扩展成一个强 抗碰撞的哈希函数。 2)若 h1 ( x) 或 h2 ( x) 是强抗碰撞哈希函数,则 h( x) h1 ( x) || h2 ( x) 强抗碰撞的哈希函数。
由此可知,设计安全的哈希函数的难题变成设计 一固定长输入的抗碰撞压缩函数。
k
如果我们不是对消息本身签名而是对消息摘要签
名,那么就希望哈希函数满足性质4)。否则对手 看到A在上的签名 h( x)后去找 x x 使 h( x) h( x) , 而且声称A是对 x 签名。 如果让对手能自己选送消息请A签名,则要求哈 希函数满足性质5)。否则对手找一对 x, x 使得 h( x) h( x) ,对手先让A对 x 签名,而后声称A是 对 x 签名。 不难看出由性质5)可以推出性质4)。但是由性质 5)不能推出性质3)。例如:g是满足性质5)的 哈希函数,定义 1 || x h( x) 0 || g ( x) 。那么取以1打头长 度为n+1的y,它的原象就是y的后面n位。
6.1.2 哈希函数的用法 哈希函数是一种消息认证码(Message Authentication Code),它对消息产生一个短小的 值。哈希函数是整个消息x的函数,消息中任意一 位改变都将引起哈希函数值的改变。所谓认证是 指一个证实收到的消息源可信且未被篡改的过程。 有多种使用哈希函数方式来提供消息认证。已知 A和B共享密钥K,如果A发送给B 1) EK ( x || h( x)) 提供保密(仅双方共享K)和认证(加 密保护哈希值). 2)
密码学哈希函数(Cryptography Hash Function)的基本思想是把哈希函数值 h( x) 看成 x 的压缩代表(称为Imprint, Message Digest), 即 x 中任意一位发生变化都将引起函数值的变化。 h( x ) 这样我们可以用对 的签名代替对 的签名。 x D, R 把任意有限长的 h : D, R h 哈希函数 输入行映射到固定长的行。哈希函数的值域与定 义域相比规模要小得多,它是“多对一”的映射。 所谓碰撞(Collision)是指定义域的两个不同元素 x1 , x 2 h( x上。哈希函数存在碰 映射到同一个象 1 ) h( x2 ) h( x ) 撞是必然的。我们把 和 x从计算意义上唯一 地联系在一起,而找到碰撞在计算上是困难的。
6.1.3 哈希函数的构造方法
大多数重要的哈希函数设计成迭代过程。 H 0 IV 为初值,H i 是第 i 阶段与 i +1阶段间的链接变量。 f 是哈希函数的压缩函数,x i 是 r 位,f ( xi , H i1 ) 是 n 位,g 是输出变换. 哈希函数 h( x) 的输入是 x 。 首先对 x 进行预处理使之长度是 r 的整倍数, x x1 x2 xt ,x i 是 r 位,1 i t 。再令 H IV , 0 对 i 1,2,, t 做 H i f ( xi , H i1 ) 。最后令函数值 h( x) g ( H t ) 。
x || EK (h( x)) 提供认证(加密保护哈希值).
3)
x || E K (Sig A (h( x))) 提供认证和数字签名(加密保护
哈希值,仅发送方能生成签名). 4) EK ( x || Sig A (h( x))) 提供保密(仅双方共享K)、认证 和数字签名. 5) x || h( x || S ) 提供保密、认证和数字签名(仅双方共 享S) . 6) EK ( x || h( x || S )) 提供保密、认证和数字签名(仅双 方共享K,S) . 对于不需要消息保密的应用中使用2)3)可以降低 计算量。由于加密软件慢、硬件费用高、加密 算法专利保护、出口限制等等因素,人们倾向 不使用带有加密的方法,而采用5)。