Hash算法与摘要
Posted better_hui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hash算法与摘要相关的知识,希望对你有一定的参考价值。
目录
一、hash算法与摘要
hash算法是一个空间到另一个空间的映射
hash算法又称摘要算法,可以将任意数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。
求模算法作为一种不可逆的计算方法,成为了整个密码学的根基。只要涉及计算机安全和加密的领域,都会有模计算的身影。散列算法也不例外。
一种最原始的散列算法,就是简单的求模,为了更加安全,我们可以加入异或过程,或者最原始文本进行运算,如移位
简单解释,hash算法是一种单向密码体制,是从明文到密文的不可逆过程,只有加密,没有解密过程。
二、特点
1、正向迅速,通过hash算法可以快速得出散列值
2、反向困难,不能通过散列值,反向输出源输入字串
3、输入敏感,输入的微小变化,即可引起输出的巨大变化
4、抗碰撞性,不同的输入,不会产生相同的散列值
三、常见hash算法的原理
散列表,是基于快速存取的角度设计的,是以空间换时间的做法。该数据结构可以理解为一个线性表,但是不是紧密排列的,可能存在空隙。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
1、hash冲突
hash冲突的问题,冲突主要取决于:
- 1、散列函数,好的散列函数的输出值应尽可能平均
- 2、处理冲突的办法
- 3、负载因子的大小。负载因子与散列函数是联动的
解决冲突的办法:
- 1、线性探查法:冲突后,线性向前试探,找到最近的一个空位置,缺点是会出现堆积的现象。
- 2、双散列函数法,在位置d冲突后,再次使用另外一个散列函数产生一个与散列表容量m 互质的数c , 依次探查 (d + n*c) %m ,使探查序列跳跃式分布
2、常用构造散列函数的方法
散列函数能使对一个数据序列的访问过程更加迅速有效
1、直接寻址法:取关键字的某个限行函数值为散列地址 H(key) = key 或者 H(key) = a * k + b
2、数字分析法,找出数字规律,减少hash冲突
3、平方取中法,关键字平方后的中间几位座位散列地址
4、折叠法,将关键字分组,三后叠加求和,最后的和就是散列地址
5、随机数法,选择随机函数,取关键字的随机值为散列地址
6、求模法
3、流行的hash算法
MD5/SHA-1/SHA-2 是目前比较流行的hash算法,而他们都是已MD4为基础涉及的。
- MD4,MIT于1990年设计,MD 是Message Digest 的缩写。基于32位操作数的位操作来实现,其输出是128位,目前已被证明不够安全
- MD5,Rivest于1991年对MD4的改进,输入仍是512位的分组,其输出是4个32位字的级联,MD5已被证明不具备抗碰撞性
- SHA , 是一个hash函数族,由NIST于1993年发布,SHA-1,输出为160位hash值,与MD4原理相同,模仿了其算法,已被证明不具备抗碰撞性。该系列还有SHA-224,SHA-256,SHA-384,SHA-512,统称为SHA-2
4、作用
1、文件校验 2、数字签名 3、鉴权协议
5、常用的Hash函数分类
1、加法hash
所谓加法hash就是把输入元素累加起来构成最后的结果。
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);
}
2、位运算hash
通过各种位运算来充分混合输入元素
static int rotatingHash(String key, int prime)
{
int hash, i;
for (hash=key.length(), i=0; i++){
hash = (hash << 4 >> 28)^key.charAt(i);
}
return (hash % prime);
}
先移位,然后再进行各种位运算是这样的类型Hash函数的主要特点。比方,以上的那段计算hash的代码还能够有例如以下几种变形:
hash = (hash<<5>>27)^key.charAt(i);
hash += key.charAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
if((i&1) == 0)
{
hash ^= (hash<<7>>3);
}
else
{
hash ^= ~((hash<<11>>5));
}
hash += (hash<<5>
hash = key.charAt(i) + (hash<<6>>16) ? hash;
hash ^= ((hash<<5>>2));
3、乘法hash
其实,“乘法哈希”的思想就是:提取关键字 key 中间 k 位数字。
公式:hash(key) = floor( M/W * ( a * key mod W) )
其中 floor 表示对表达式进行下取整
1、通常设置 M 为 2 的幂次方。
2、W 为计算机字长大小(也为2的幂次方)。
3、a 为一个非常接近于W的数。
4、除法hash
hash = hash ^ (hash》》10) ^ (hash》》20)
5、查表hash
static int crctab[256] = {
0x00000000, 0x77073096}
int crc32(String key, int hash)
{
int i;
for (hash=key.length(), i=0; i
hash = (hash 》》 8) ^ crctab[(hash & 0xff) ^ k.charAt(i)];
return hash;
}
6、混合hash
混合Hash算法利用了以上各种方式。各种常见的Hash算法,比如MD5、Tiger都属于这个范围。它们一般很少在面向查找的Hash函数里面使用。
以上是关于Hash算法与摘要的主要内容,如果未能解决你的问题,请参考以下文章