LOADING...
LOADING...
LOADING...
当前位置: 玩币族首页 > 区块链资讯 > 什么是哈希函数?

什么是哈希函数?

2020-04-14 liao 来源:链闻

哈希函数 Hash Function,也叫做「散列」、「杂凑」函数或者算法。理论上讲,哈希函数就是一种数学流程,将任意大小的输入数据放入该流程,然后返回固定大小的输出数据。把输入数据压缩成摘要,使得数据量变小,将数据的格式固定下来。

更具体地讲,提取任意长度的字母序列作为输入(通常称为 string)进行杂糅、打乱混合,然后返回一个固定长度、格式的字母序列。无论这个输入 string 是单一字母、单词、句子还是整部小说,而输出的长度(叫做摘要 digest)永远相同。

举个例子,给定一个输入 x,哈希函数会算出相应的输出 H(x)。其主要特征是:

输入 x 可以是任意长度的字符串输出结果即 H(x) 的长度是固定的计算 H(x) 的过程是高效的(对于长度为 n 的字符串 x,计算出 H(x) 的时间复杂度应为 O(n)

这种类型的哈希函数,常见用例就是存储密码。

当你使用任何一种网络服务创建需要密码的帐号时,此类密码都是通过哈希函数运行的,所存储的就是该密码信息的哈希摘要。当你输入密码以登陆帐号时,相同的哈希函数会去运行你输入的密码,然后服务器就会检查其结果是否与存储的摘要相匹配。这意味着黑客即使能够访问用于存储哈希的数据库,因无法轻易找到生成某一特定哈希的密码,所以不可能立即破解。

通过该函数创建的,叫做散列值(hash values、hash codes、hash sums 或 hashes)的指纹,通常用一个短的随机字母和数字组成的字符串表示。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到。

所说的固定长度,比如 128 位,依次进行 hash 运算,然后用不同的方法迭代即可(如前一块 hash 值与后一块 hash 值进行异或)。如 128 位不够,用 0 或者 1 补全随意,算法中约定即可。

由于用途的不同,hash 在数据结构中的含义和密码学中的含义并不相同,所以在这两种不同的领域里,算法的设计侧重点也不同。

预备小知识:

抗碰撞能力:对于任意两个不同的数据块,其 hash 值相同的可能性极小;对于一个给定的数据块,找到和它 hash 值相同的数据块极为困难。

抗篡改能力:对于一个数据块,哪怕只改动其一个比特位,其 hash 值的改动也会非常大。在用到 hash 进行管理的数据结构中,比如 hashmap,hash 值(key)存在的目的是加速键值对的查找,key 的作用是为了将元素适当地放在各个桶里,对于抗碰撞的要求没有那么高。换句话说,hash 出来的 key,只要保证 value 大致均匀的放在不同的桶里就可以了。但整个算法的 set 性能,直接与 hash 值产生的速度有关,所以这时候的 hash 值的产生速度就尤为重要,以 JDK 中的 String.hashCode() 方法为例:

public int hashCode() { int h = hash; //hash default value : 0 if (h == 0 && value.length > 0) { //value : char storage char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }

很简洁的一个乘加迭代运算,在不少的 hash 算法中,使用的是异或 + 加法进行迭代,速度和前者差不多。在密码学中,hash 算法的作用主要是用于消息摘要和签名,换句话说,它主要用于对整个消息的完整性进行校验。在应用场景里,对于抗碰撞和抗篡改能力要求极高,对速度的要求在其次。一个设计良好的 hash 算法,其抗碰撞能力是很高的。以 MD5 为例,其输出长度为 128 位,而对于两个相似的字符串,MD5 加密结果如下:

MD5("version1") = "966634ebf2fc135707d6753692bf4b1e"; MD5("version2") = "2e0e95285f08a07dea17e7ee111b21c8";

可以看到仅仅一个比特位的改变,二者的 MD5 值截然不同。

到这里,你估计会问,有没有这样一个算法,使得对于任何一个给定的输入,此算法都会输出一个固定的均匀随机的输出?答案是密码学家们也至今没有构造出着这样一个算法,但倾向于这个算法存在,而且有不少的密码学算法构造和这个假设有关。这个假设叫做 Random Oracle 随机预言机。

Python 简单哈希函数

你可以使用 Python 编程语言,实验哈希值。

首先,打开终端,输入 Python 并点击 Enter 键,进入 Python REPL,直接试用 Python 命令,而不是在单独的文件中编写程序。输入以下数值,在每行之后敲击 Enter 键,并在标记处输入 TAB 键:

import hashlib def hash(mystring): [TAB] hash_object = hashlib.md5(mystring.encode()) [TAB] print(hash_object.hexdigest()) [ENTER]

这样你就创建了一个函数 hash(),该函数将计算出某一特定的使用 MD5 哈希算法的字符串的哈希值。将字符串插入上述的括号()中便可运行该函数。例如:

hash(“ChainScoop rocks”)

按下 Enter 并查看该字符串的哈希摘要。

你将看到在同一字符串上调用该哈希函数将会总是生成相同的哈希,但添加或改变其中的某一个字符将会生成一种完全不同的哈希值:

hash("ChainScoop rocks") => 7ae26e64679abd1e66cfe1e9b93a9e85 hash("ChainScoop rocks!") => 6b1f6fde5ae60b2fe1bfe50677434c88

  • 添加新手交流群:币种分析、每日早晚盘分析
  • 添加虎哥微信,一对一亲自指导:hugelunbi02
  • —-

    编译者/作者:liao

    玩币族申明:玩币族作为开放的资讯翻译/分享平台,所提供的所有资讯仅代表作者个人观点,与玩币族平台立场无关,且不构成任何投资理财建议。文章版权归原作者所有。

    LOADING...
    LOADING...