什么是哈希?
简单来说,哈希就是输入任意长度的字符串都可以产生固定大小的输出。在比特币这种加密货币中,交易就是输入,然后经过哈希算法(比特币采用的是 SHA - 256),产生固定长度的输出。
下面就是使用 SHA-256 算法的例子:
通过上面的例子可以看出,无论输入大或者小,输出都是固定256比特的长度。这一特性在处理大量数据和交易时是至关重要的。基于哈希这一特性,我们不用记输入数据是多么大,只需要记住hash值即可。在我们进一步讨论之前,我们首先需要看看哈希函数的各种属性以及它们在区块链中的实现方式。
加密哈希函数
加密哈希函数是一类特殊的哈希函数。为了让哈希函数达到密码安全,需要有以下几个特性:
确定性(Deterministic)
对于同一个输入,无论用哈希函数计算多少次,都会得到相同的结果。
快速计算
对于输入的字符串,能在合理的时间内算出哈希函数的输出,否则会影响系统的性能。
隐秘性
如果我们已知字符串 A 的哈希值是 H(A),那么我们没有可行的办法算出 A 是什么。注意,这里说的是 “不可行” 而不是 “不可能”。 比如下面的例子中,知道输出哈希值是可以算出输入的。
假如我们掷骰子🎲,输出就是骰子上数字的哈希值。那么在知道输出的哈希值情况下,我们能否知道骰子上的数字呢?因为哈希函数是具有确定性的,相同输入的哈希值一定相同,所以我们只需计算 1-6 的哈希值是什么,然后对比就能知道骰子上的数字是什么了。
当然,我们能够根据哈希值猜出骰子的数字,是因为输入值只有 6 种可能性。如果我们的输入值来自一个分散的集合,那么想要通过输出推导出输入的唯一方法可能就是“暴力破解法”了。暴力破解就是,任意选择一个输入,计算其哈希值,与现有哈希值对比是否一致,不断重复这一过程,直到找到一个输入的哈希值与现有哈希值一致。
那么暴力破解法是否可行呢?假设我们现在处理的是128位的哈希值。
最好的情况:第一次尝试就找到了答案,但这种情况可以说是几乎不可能的,比中大乐透还难。
最坏的情况:在尝试 2^128 -1 次后得到了答案,也就是试过了所有可能的输入才找到。
平均的情况: 在平均情况下,我们要尝试 2^128 / 2 = 2^127 次之后才能找到答案。2^127 = 1.7 X 10^38 , 也可以说是个天文数字了。
所以,在已知哈希值的情况下, 尽管可以通过暴力破解的方法找到输入的字符串是什么,但这会花费很长长长长长的时间,所以不用担心。
抗篡改能力
对于任意一个输入,哪怕是很小的改动,其哈希改变也会非常大。比如 “This is a test” 对应的哈希值是C7BE1ED902FB8DD4D48897C6452F5D7E509FBCDBE2808B16BCF4EDCE4C07D14E
, 而 “this is a test” 对应的哈希值是 2E99758548972A8E8822AD47FA1017FF72F06F3FF6A016851F45C398732BC50C
。
看上面的例子,即便只改变了输入字符串第一个字母的大小写,输出hash值也是完全不同的。用前段时间比较流行的区块链撸猫游戏类比一下,“This is a test” 的哈希值对应猫可能是这样的: