哈希函数是什么,在区块链中有什么用
哈希函数是什么?
哈希函数,又叫散列函数、散列算法,是一种从任何一种数据中创建小的数字“指纹”(也叫做摘要)的方法。什么意思呢?就是说,你输入任何长度、任何内容的数据,哈希函数输出固定长度、固定格式的结果,这个结果类似于你输入数据的指纹。只要输入发生变化,那么指纹一定会发生变化。不同的内容,通过哈希函数得到的指纹不一样。这就是哈希函数。
图 1 不同的输入,通过sha256函数都生成相同格式、相同长度的指纹
那么,哈希函数在区块中有什么用?
答案有以下两点:
- 快速验证。哈希函数在区块链中,生成各种数据的摘要,当比较两个数据是否相等时,只需要比较他们的摘要就可以了。例如,比较两个交易是否相等,只需要比较两者的hash值,快捷又方便。
- 防止篡改。传递一个数据,要保证它在传递过程中不被篡改,只需要同时传递它的摘要即可。收到数据的人将这个数据重新生成摘要,然后比较传递的摘要和生成的摘要是否相等,如果相等,则说明数据在传递过程中没有被篡改。
- 用于POW共识算法工作量证明。这个主要是在pow的共识算法中使用。详细说来,就是给定一定的数据,然后让你寻找其他的数据,合并起来计算出来的hash值小于某个值。比特币、目前的以太坊,都是使用的POW共识。
图 2 pow算法中哈希函数的应用
Ok,看完上面部分的同学已经可以给人吹牛逼了,如果不想继续深究的话可以去做别的事情了。下面我们再延升一下哈希函数的特性及在区块链中的演进过程。
Hash函数的特性
- 不定长度输入,固定长度输出
所谓不定长度输入,固定长度输出,我们在前文中已经讲过了。就是不管输入的数据是多长,是多大,输出的数据长度、格式都是固定的。比如你选择sha256,那么你的输出就是256位。
- 抗碰撞性
如果x不等于y,但是H(x)等于H(y),那么我们就说H()这个函数不具有抗碰撞性。反之,我们就认为其是具有抗碰撞性的。
图 3 碰撞示意图
总结一句话:如果X不等Y,那么H(x)也不等于H(y),那么我们就说H()这个函数具有抗碰撞性。一个好的hash函数是一定要具有抗碰撞性的。
- 不可逆性(单项性)
给定哈希函数H()和输入数据,可以很方便的求解出哈希值,但是给定哈希值和哈希函数几乎不能求解出输入数据是什么,这就是不可逆性,也叫做单向性。
一个好的哈希函数必然具备:不定长输入固定长输出、抗碰撞性、不可逆性这三个特点。
区块链中hash函数的演进
- Sha256
Sha全称是Secure Hash Algorithm,是美国国家安全局(NSA)设计,美国国家标准与技术研究院(NIST)发布的一系列密码散列函数。它经历了SHA-0、SHA-1、SHA-2、SHA-3系列的发展。比特币采用sha256算法属于SHA-2系列,在中本聪发明比特币时是最先进最安全的算法之一。
- Scrypt
随着显卡挖矿和矿池的出现,社区担心算力的集中,违背去中心化的原则。于是,莱特币提出了Scrypt算法。莱特币除了此算法外,其它部分完全fork比特币。和sha256相比,此算法需要更多的内存和更长的计算时间,能够抵御矿机。但是此算法没有经过严格的安全审查和全面论证。
- 串联算法
所谓的串联算法,同我们初中物理里面所说的串联是同样的道理,就是使用很多种hash算法经过多轮运算,前一轮结果用于后一轮hash的输入。市面上的X11、X13、X15等就是这种算法。
- 并联算法
所谓的并联算法,也和物理中的并联差不多,即先将输入用不同的hash函数求解,然后将求解的结果混淆,形成最终的hash算法的结果。
- ETHASH
Ethash是值得一提的hash算法。它是以太坊中使用的pow的hash算法。该算法能抵御矿机,基本上能做到ethash挖矿时和CPU性能无关,却和内存大小和内存带宽成正比。该算法的流程如下:
- 对于每一个块,首先计算一个种子(seed),该种子只和当前块的信息有关;
- 然后根据种子生成一个32M的随机数据集(Cache);
- 紧接着根据Cache生成一个1GB大小的数据集合(DAG),DAG可以理解为一个完整的搜索空间,挖矿的过程就是从DAG中随机选择元素(类似于比特币挖矿中查找合适Nonce)再进行哈希运算。