Java之Hash算法介绍

相关文章:
Java之HashMap
Java之equals和hashcode方法

 

什么是hash?

英文意思为“无用信息”,计算机通常音译为“哈希”,名字由来:可能是最终形成的哈希表里面,是各种看起来毫无意义的描述值的混合。

 

什么是Hashing?

散列法,或者叫哈希法,是一种将字符组成的字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,由于通过更短的哈希值比用原始值进行数据库搜索更快,这种方法一般用来在数据库中建立索引并进行搜索,同时还用在各种解密算法中。

 

什么是hash表?

又称散列表,通过把关键码值(Key value)映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
Hash表大小的确定也非常关键,如果Hash表的空间远远大于最后实际存储的记录个数,则造成了很大的空间浪费,如果选取小了的话,则容易造成冲突。在实际情况中,一般需要根据最终记录存储个数和关键字的分布特点来确定Hash表的大小。还有一种情况时可能事先不知道最终需要存储的记录个数,则需要动态维护Hash表的容量,此时可能需要重新计算Hash地址。
 

 

日志输出一个对象

java String在打印这个类型的实例对象的时候总是显示为下面的形式
test.Test$tt@c17216
上面例子中:

  • test.Test是类名,
  • $tt是我自己写的内部类,
  • @后面这一段是test这个实例类的hashcode的16进制!它使用了Object 里面的toString()方法
    return getClass().getName() + “@” + Integer.toHexString(hashCode());  

 

哈希值常见应用场景

哈希算法是一个较为复杂的运算,它的输入可以是字符串、数据、任何文件,经过哈希运算后,变成一个固定长度的输出,该输出就是哈希值。这个算法有一个很大的特点,就是你不能从结果推算出输入

1)快速数据搜索。比如,在数据库中存储一些人名,排列方式可能是这样:Abernathy, Roscoe,Moore,Smith 所有名字均按字母排序......利用名字来作为数据库的索引值。数据库搜索算法首先会逐个字符进行名字的搜索,直到找到为止。但是如果利用散列法对每个名字进行了转换,产生一个四位的索引值(ps:4位只是举例,位数长度取决于数据库大小),像下面这样:7864 Abernathy,9802 Roscoe,1990 Moore,8822 Smith.....,下次搜索名字时,就先搜索哈希并对数据库中的每个值进行一一对应。通常来讲,寻找四位的数字比寻找未知长度的字符串要来得快得多。毕竟寻找数字时每一位只有10种可能,而名字的长度未定,且每一位都有26种可能。

2)比方说我们从服务器下载一个软件,如果这个软件被黑客更改了,那么我们下载的就不是原来的软件,如果是银行客户端可能就会有账户被盗的风险,但是有了哈希运算后,我们可以把下载的软件经过哈希运算后得到哈希值,然后把哈希值跟软件发行方公布的哈希值对比,就知道软件是否有被篡改了。
同理还有:
对数据签名后的加密解密工作,这种签名可以用来对收发消息时的用户签名进行鉴权。
先对数据data进行签名(RSA),得到数字签名sign,对数据签名sign进行hash函数,得到信息摘要sign2,然后将数字签名sign和转换后的信息摘要sign2分别独立的发送给接收人。接收人通过利用和发送人一样的哈希函数,可以从数字签名获得一个信息摘要sign3,然后将此摘要同传送过来的摘要sign2进行比较,若是sign3 == sign2,则表示数字签名有效。

3)比如我们登陆网站的密码,后端服务器保存的也是密码的哈希值而不是密码明文,服务器只用输入匹配哈希就可以了,而不是直接比对密码明文,可以有效的保护用户隐私。

有人问:你说的是MD5吧?没错!其实MD5就是目前应用最广泛的一种Hash算法

 

Hash函数的特点

  • 不能从结果逆推得到输入。根据哈希函数得到的结果,是不可能逆推出来的。
  • 好的哈希函数还应该避免对于不同输入产生相同的哈希值的情况发生。如果产生了哈希值相同的情况,称为冲突。
  • 可接受的哈希函数应该将冲突情况的可能性降到非常小。
  • 虽然能够采用一些办法去减少冲突,但是冲突是无法完全避免的。因此需要根据实际情况选取解决冲突的办法。

 

Hash函数常见算法

1)余数法:先估计整个哈希表中的表项目数目大小。然后用这个估计值作为除数去除每个原始值,得到商和余数。用余数作为哈希值。因为这种方法产生冲突的可能性相当大,因此任何搜索算法都应该能够判断冲突是否发生并提出取代算法。

2)折叠法:这种方法是针对原始值为数字时使用,将原始值分为若干部分,然后将各部分叠加,得到的最后四个数字(或者取其他位数的数字都可以)来作为哈希值。

3)基数转换法:当原始值是数字时,可以将原始值的数制基数转为一个不同的数字。例如,可以将十进制的原始值转为十六进制的哈希值。为了使哈希值的长度相同,可以省略高位数字。

4)数据重排法:这种方法只是简单的将原始值中的数据打乱排序。比如可以将第三位到第六位的数字逆序排列,然后利用重排后的数字作为哈希值。

哈希函数并不通用,比如在数据库中用能够获得很好效果的哈希函数,用在密码学或错误校验方面就未必可行。
在密码学领域有几个著名的哈希函数。这些函数包括 MD2、MD4以及MD5,
利用散列法将数字签名转换成的哈希值称为信息摘要(message-digest),
另外还有安全散列算法(SHA),这是一种标准算法,能够生成更大的(60bit)的信息摘要,有点儿类似于MD4算法。

 

 

资料源自互联网,经综合整理而成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值