散列(Hash)

来源:互联网 发布:淘宝打假赚钱怎么赚钱 编辑:程序博客网 时间:2024/05/21 10:55

散列表(Hash table)又称哈希表。散列变换是一种压缩映射,可以将任意长度的消息压缩到某以固定长度的数值或索引值的方法。搜索时先将散列值并对数据库中的每个值进行一一比较,寻找数字比寻找未知长度的字符串要更快,所以通过更短的哈希值比用原始值进行数据库搜索更快。这种方法一般用来在数据库中建立索引并进行搜索,同时还用在各种解密算法中。

将任意长度的输入( pre-image,又叫做预映射),通过散列算法,变换成固定长度的输出,该输出就是散列值。

散列算法,也称为哈希函数——哈希的英文意思为“无用信息”,因此哈希函数一词的由来可能是因为最终形成的哈希表里面是各种看起来毫无意义的描述值的混合。除用来快速搜索数据外,散列法还用来完成签名的加密解密工作,这种签名可以用来对收发消息时的用户签名进行鉴权。先用哈希函数对数据签名进行转换,然后将数字签名本身和转换后的信息摘要分别独立的发送给接收人。通过利用和发送人一样的哈希函数,接收人可以从数字签名获得一个信息摘要,然后将此摘要同传送过来的摘要进行比较,这两个值相等则表示数字签名有效。

散列值的特点

确定性

如果在同一函数中,两个散列值不相同,那么这两个散列值的原始输入也不相同。这个特性是散列函数具有确定性的结果。

不唯一性

因为散列值的空间有限,通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值。如果在同一函数中,如果两个散列值相同,两个输入值很可能是相同的,但并不一定相等。

一些简单的散列函数

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

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

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

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

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

利用哈希函数对数据库中的原始值建立索引,以后每获取一次数据时都要利用哈希函数进行重新转换。因此,哈希函数始终是单向操作。没有必要通过分析哈希值来试图逆推哈希函数。实际上,一个典型的哈希函数是不可能逆推出来的。好的哈希函数还应该避免对于不同输入产生相同的哈希值的情况发生。如果产生了哈希值相同的情况,称为冲突。可接受的哈希函数应该将冲突情况的可能性降到非常小。

散列表

散列表是散列函数的一个主要应用,使用散列表能够快速的按照关键字查找数据记录。(注意:关键字不是像在加密中所使用的那样是秘密的,但它们都是用来“解锁”或者访问数据的。)例如,在英语字典中的关键字是英文单词,和它们相关的记录包含这些单词的定义。在这种情况下,散列函数必须把按照字母顺序排列的字符串映射到为散列表的内部数组所创建的索引上。

散列表散列函数的几乎不可能的理想是把每个关键字映射到唯一的索引上(参考完美散列),因为这样能够保证直接访问表中的每一个数据。一个好的散列函数(包括大多数加密散列函数)具有均匀的真正随机输出,因而平均只需要一两次探测(依赖于装填因子)就能找到目标。

同样重要的是,随机散列函数几乎不可能出现非常高的冲突率。但是,少量的可以估计的冲突在实际状况下是不可避免的(参考生日悖论)。在很多情况下,heuristic散列函数所产生的冲突比随机散列函数少的多。Heuristic函数利用了相似关键字的相似性。

0 0
原创粉丝点击