hashing

Hashing定义了一种将 字符组成的 字符串转换为固定长度(一般是更短长度)的数值或索引值的方法,称为散列法,也叫哈希法。由于通过更短的哈希值比用原始值进行数据库搜索更快,这种方法一般用来在数据库中建立索引并进行搜索,同时还用在各种解密算法中。通过一个简单的例子对此进行说明,比如,在数据库中存储一些人名,排列方式可能是下面这样:

Abernathy, Sara

Epperdingle, Roscoe

Moore, Wilfred

Smith, David

  所有名字均按字母排序......

  可以利用这些名字本身来作为数据库的索引值。数据库搜索算法首先会逐个字符的进行名字的搜索,直到找到为止。但是如果利用散列法对每个名字进行了转换,就可能为数据库中的每一个名字产生一个四位的索引值,其中位数长度取决于数据库中到底有多少个人名,象下面这样:

7864 Abernathy, Sara

9802 Epperdingle, Roscoe

1990 Moore, Wilfred

8822 Smith, David

  等等......

  这样,下次搜索名字时,就先搜索哈希并对数据库中的每个值进行一一对应。通常来讲,寻找四位的数字比寻找未知长度的字符串要来得快得多。毕竟寻找数字时每一位只有10种可能,而名字的长度未定,且每一位都有26种可能。

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

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

  下面列出了一些相对简单的哈希函数:

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

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

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

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

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

你可能感兴趣的:(算法)