“人类历史上第一次,全世界各地的人,花费巨额的成本,争前恐后地寻找美学意义上的数学运算结果。”

—卫sir

Beeple加密艺术作品《区块链》

说起区块链,似乎大家都懂一点,再往细里一问,似乎又都不懂了。

比如,你问一个人:为什么要挖矿,挖的到底是啥。

怕是没几个明白人。

本文就是要给你讲明白!

前言

人们一说起区块链,就常常说防篡改防篡改,那么,这个防篡改是怎么做到的呢。

主要靠HASH。

人们所常说的挖矿,其实是在挖HASH。

挖一个长得很好看的HASH。

但,什么是HASH?

外行人是说不清的,内行人,似乎也很少能给外行人讲明白。

很多人喜欢用比喻的方式给外行人讲HASH,其实,你就是弄100个比喻(什么麻将、扑克、骰子啥的),不懂HASH的人还不懂。

他们中比较傻白甜的,甚至会想,挖矿是在挖麻将吗?

真正想弄明白HASH,就让他看看HASH长什么样子呗!!

HASH到底是个啥

HASH是一个算法,你给它一串数,它给你一串数。

你给它的叫输入,它给你的叫输出。

也就是说,将数据输入给HASH函数,HASH函数输出一串数。

HASH( 输入 )= 输出

这就好比你把一头猪输入给一个香肠机,香肠机给你输出一段香肠。

看个例子吧,我们以最常见的HASH算法MD5为例。(当然,有很多种HASH算法,MD5是其中最知名的一个。)

MD5 ("weijianfan") = c49262b1117b9fd1d6ebd74aaa016f3e

上面这个例子中,“weijianfan”是输入,后面那串数是输出。

再如:

MD5 ("weiyuerenhua") = a799c7c504a1a80f95ebe69a86c42637

注意,HASH函数有个重要的特点,不管输入多长,输出都是固定长度的。

当然,和一般的算法一样,只要输入不变,输出是不变的。

比如MD5,输入是不限制长度的,输出就是128位的二进制,也就是16个字节的十六进制。像上面第一个例子里,c4就是一个字节,代表了8位的二进制,即11000100,最后那个3e也是一个字节,也即00111110

我们把输入搞长点:

MD5 ("In Math We Trust.") = 767fa54f12bab6b71fb411f265814bb7

把汉字作为输入:

MD5 ("博鳌亚洲论坛2021年年会数字支付与数字货币分论坛4月18日晚举行。") = 36b5e89c797d22d14ccefe4ec79f56c2

再搞长点:

MD5 ("Andreas M. Antonopoulos is a noted technologist and serial entrepreneur who has become one of the most well-known and well-respected figures in bitcoin. An engaging public speaker, teacher, and writer, Andreas makes complex subjects accessible and easy to understand. Andreas advises multiple technology startups and speaks regularly at conferences and community events around the world.") = 5ac503b01e213d4794d92134096ad313

长一点的汉字:

MD5 ( "Andreas M. Antonopoulos 是⼀位著名的技术学家和连续创业企业家,⽐特币界最著名和倍受尊敬的⼈物之⼀。⾝为⼀名迷 ⼈的公共演说家、教师和作家,他善于把复杂的问题变得简单⽽易于理解。作为⼀名顾问,他则帮助初创者认知、评估并指 引减⼩安全和业务风险。") = 90f039293e0b3da5516e251b93434795

HASH还有一个特点,只要输入有一点点的变化,输出都会完全不同,就好像输入是完全不同的。

比如把上面这段文字中“一位”里的“一”字删掉,再做HASH:

MD5 ("Andreas M. Antonopoulos 是位著名的技术学家和连续创业企业家,⽐特币界最著名和倍受尊敬的⼈物之⼀。⾝为⼀名迷 ⼈的公共演说家、教师和作家,他善于把复杂的问题变得简单⽽易于理解。作为⼀名顾问,他则帮助初创者认知、评估并指 引减⼩安全和业务⻛险。") = 159c9d192e45fbd2eaa0c3f068a78508

看到了吧,输入有微小的变化,输出会完全不同。

HSAH对输入是不挑的,不管是字符串,还是文件,不管是文本、图像、视频,只要是数字的,都当作二进制输入就是了。

比如,把下面这幅图像给MD5,可以得到:

MD5 (Emily Blunt.jpg) = b818d284ef28f733c701f7bc1ee5f669

图|艾米莉布朗特,英国最受欢迎的女演员

如果你的电脑上有md5工具,你就可以试试自己做HASH,比如在mac电脑里,在“终端”中输入md5 -s "xxx",或者md5 1.txt就可以对字符串或者文件进行md5。

若干G的视频文件也没问题:

MD5 (伟大的转折-01.mp4) = 9093c85d13f79609978f52c48e19aa65

图|38集革命历史剧《伟大的转折》,遵义会议会址

你哪怕是改动了这个视频中任何一帧的任何一个像素,MD5算出来的结果都截然不同。

所以,判断一个文件是不是被人改动过,算一下HASH就行,HASH只要没变,文件就没有被动过。(前提是这个HASH算法还不错!)

现在你对HASH大概有点印象了吧,反正只要是数字的输入,都能给你整出一段固定长度的输出,而且个个都不一样。

啥是好看的HASH

答:好看的HASH就是前面有很多位0的HASH。—卫sir

HASH输出是比较均匀分布的,基本上,你对任意16个不同的输入做HASH,第1位是0的概率是1/2(大概有8个),前两位是0的概率是1/4,前3位是0的概率是1/8,前4位都是0的概率为1/16。

我们做个实验看看对不对,以下的输入都是随意给的:

1、MD5 ("ionnoouyd") = c78a3b60314d11fc9e739aef407989f5
2、MD5 ("njjiuhbh") = 9aee0690f6002392b2c6fc0d2224adb2
3、MD5 ("88990933") = b19bf0928fc649d99b1cdf02748ae88e
4、MD5 ("-sr&&fvbgt") = 24cc429a2636ac1b9092cf3f681bba09
5、MD5 ("区块链技术") = 649e6048a32c09299e1c952347ccac7e
6、MD5 ("hashcash is very good") = 8015b497b3a9bd6ca7ba1213a731b1a1
7、MD5 ("CC0-MIT") = cd08de7f0f219d8e13437c65974f9773
8、MD5 ("beihaimuchang") = 7cd9a24efce05bbceb01c9020d904294
9、MD5 ("wqqwrr2") = 1cb1797fb57add01523fbd6e86ca2b73
10、MD5 ("1123ed") = ae49266f10e08922780afeb664fd61dc
11、MD5 ("hello world") = 5eb63bbbe01eeed093cb22bb8f5acdc3
12、MD5 ("niahoa...") = 5d3e60365ff999e68a932da4619a129b
13、MD5 ("blockchain") = 5510a843bc1b7acb9507a5f71de51b98
14、MD5 ("随机发均出版后我给") = 18eb95457ec90f1c33fa5914579730d7
15、MD5 ("93002712") = 0abf0bd1dbb35366c56b26d157686f0f
16、MD5 ("13811031123") = 940ca3847eec1e99e716975bc7096c8d

前面说过,MD5输出是128位的,上面是用16进制展示的,比如第一个输出的第1字节是“c7”,第二个输出的第1字节是“9a”,用2进制表示就是“11000111”、“10011010”。依此方法,上面16个HASH输出也就是(省略号代表省略了后面的位):

HASH01  c7………:11000111……………………
HASH02  9a………:10011010……………………
HASH03  b1………:10110001……………………
HASH04  24………:00100100……………………
HASH05  64………:01100100……………………
HASH06  80………:10000000……………………
HASH07  cd………:11001101……………………
HASH08  7c………:01111100……………………
HASH09  1c………:00011100……………………
HASH10  ae………:10101110……………………
HASH11  5e………:01011110……………………
HASH12  5d………:01011101……………………
HASH13  55………:01010101……………………
HASH14  18………:00011000……………………
HASH15  0a………:00001010……………………
HASH16  94………:10010100……………………

你们可以数数,前1位、前2位、前3位、前4位是0的HASH个数,是不是和上面说的概率差不多?

当然,我最喜欢的是那个前4位都是0的,HASH15,它在这16位里面是长得最好看的。

它出现的概率大概就是每16个HASH里面出一个。也就是2^4次出一个。

那么,多少次才会出来一个前20位都是0的HASH呢。

2^20次。

2^20就是2的20次方,就是1,048,576这么多啦!一百万还多啦!所以想在你的电脑上找到它,得算一会呢~

前20位是0,就是16进制前5个数为0,大概就是下面这个样子

00000fc7f1d91e9053995f707a90971d

是不是很好看?

至少比前面出现过的都好看。

当然还不是最最好看的,全宇宙举世无双好看的那个HASH,是全0。

这个全0的HASH,应该还从来没有被算出来过,不知道人类灭亡前能否靠运气找出来。

总之,我说的好看,就是前面有很多个0。

0越多,越好看。

好的HASH算法有什么特点?

注意HASH算法有很多,比如MD5、SHA-1、SHA-2等,再如BTC用的SHA-256和RIPEMD-160等。

至少有这么两个特点:

1、对于任意两个不同的输入,应该产生不同的输出。(这叫抗碰撞)

2、正向计算很容易,反过来从输出倒推输入,就非常难,只能靠暴力猜。(这叫不可逆)

先看第一个特点:抗碰撞

一个好的HASH算法,对于任意两个不同的输入,应该产生不同的输出。

事实证明,MD5、SHA-1不能算很好的HASH算法,因为王小云院士等人,已经可以找到两个不同的输入,产生相同的HASH输出。具体可以看看相关文章12

如何形象理解这个特点呢?

首先,这个HASH算法的输出必须要有一定的长度,如果长度不够,肯定会有重复的。比如假设一个HASH算法,输出只有1位,输出不是0就是1,那是不是运行两、三次,就能找到了不同输入相同输出了呢!如果输出只有两位,这个HASH的输出就只有4种可能,00、01、10、11,那是不是运行四、五次,就能找到不同输入相同输出了呢!

所以MD5有128位这么长,SHA-256有256位这么长!

其次,要保障HASH值是非常随机、非常均匀地落在整个输出空间上。而且输入有一点点的不同,输出都会全然的不同。

这样,就有了一种ID的效果,HASH就像是每个输入各异的“指纹”。比如,你把1000万份不同的文件都做了HASH,每份文件都获得一个独一无二的HASH值,就可以把这个当作是一个文件的ID。每个ID都指代了一个独一无二的文件,如果再遇到ID相同的,就表明遇到相同的文件了。

再次,要能理解,输出的空间是非常大的。

对于像RSA-256这样的算法,其输出位数为256位,那么可能的值就会有10^78个(也即2^256个),这是多么大的一个数呢?

全地球沙子的数量(不只是海滩上的,而是所有),有人估算过,大致是7*10^21个,还不到10^22个。

全宇宙星球的数量,也大致不过7*10^22个,还不到10^23个。

你给它两个不同的输入,它产生相同输出的概率,比下面这个例子中的概率还要小得多:

你随便在一个星球上选了一粒沙子,另外一个人,在完全不受你影响的情况下,也随机在某个星球上随机选了一粒沙子,结果你俩选择了同一粒沙子!然后你俩还不约而同地选择了这个沙子中的同一个原子!

现在看第二个特点:不可逆

一个好的HASH算法,要求正向计算很快,但反向几乎不可能。

比如,我现在有一个BTC私钥,形如:

5HvrDrdQ9EpJTcJHXuctU9vUjydzuZ1????????????????DCHa

为了保密,我把其中16个字符用?代替。

计算出这个私钥的MD5值为:630a0cec43d49095027b224ea0f2b317

那么,请问,全世界的黑客,有没有能力通过破解MD5,得到我这个私钥呢?

答案是:按照现在的能力,不能。

黑客的做法,只能是,不断尝试这16个?号可能的组合,计算其MD5值,以期有一天能算出相同的MD5值。

但这种暴力猜解需要很长时间。(大致毛估一下,以目前的技术,如果全世界黑客联合起来,拥有类比全球BTC挖矿那么大的算力,那也至少要算5年。)

那么,挖矿是在干什么

2021年6月13日18:09:30,BTC矿工们挖出一个HASH:

00000000000000000009813c8a3b95e3a75d878419547b7fe4dd71f9dc71da72

看看这个HASH多么漂亮!它的前面有多少个0!

上面是用16进制表示的,所以,每个0其实是二进制的0000,所以上面那个HASH,前面是19*4=76个二进制的0!

这个HASH是一个区块的HASH(严格的说,是这个区块头部的HASH)。

最近每10分钟就出一个这么漂亮的。

矿工们做了多少次HASH才做出这么漂亮个HASH呢?

不知道,反正平均2^76次才会出现一个这样的,你说做了多少次呢。

他们这么费劲挖这个,图啥呢?

图这个区块奖励的BTC。

挖出这个区块的矿工(可能是很多人一起挖的),得到了6.54164549个BTC,其中6.25个是系统奖励的,剩下的是赚的手续费。

哦,我大致明白HASH了,区块又是什么?

现在给大家讲讲区块链的老祖宗—BTC—的工作原理。

如果一遍看不懂,就看两遍,两遍看不懂,就大声读第三遍。

一般都能读懂。

1、互联网中若干个节点(节点就是计算机啦!)同时运行BTC软件。这些软件是开源的,谁都可以下载了来运行(本文说的节点是指全功能节点,全球目前大约有1000个左右)。

2、人们如果要发起BTC转账(也即交易),就让某个节点在互联网广播转账信息,此交易很快传遍全网每个节点。每个节点都会检查它所收到的交易是否符合逻辑(比如有没有那么多钱来转账),如果不对,就会把这个交易抛弃掉。

转账就是:张三给李四发送1个BTC,王五给赵六发送0.1个BTC,诸如此类。差不多就是这个意思,每一笔转账也叫一个交易。

3、平均每隔一段时间(平均10分钟),网内某个节点就会率先打包出一个区块,区块里面含有这段时间的所有交易数据,这个区块会广播到全网,每个节点都会收到该区块(大小在1M左右)。

3a:打包是有条件的,这个区块的头部的HASH值必须很好看。3b:平均10分钟才出一个,这是由挖矿难度导致的。难度是动态调整的,每两周调整一次,调整使得全网平均每10分钟才能挖出一个区块。在一个完全去中心化的网络中,难度调整是如何做到的呢?方法是:每过2016个区块,所有节点都会自发地调整难度(写在代码里了)。新的难度是由最近2016个区块的花费时长与20160分钟(两周)比较后调整得出的。如果花费时间短于20160分钟,就将难度调大一些,反之亦然则调小一些。难度可以简单地理解为要求HASH值前面有多少个0。3c:每个10分钟内,世界上都会发生很多笔交易,这些交易都等着打包(最终只有打包在区块里的交易才被人们承认)。每个试图打包的矿工,把自己收到的、尚未打包的交易,放在区块里(由于区块大小的限制,平均一个区块能装大约2000多个交易),然后通过填充区块中的随机数区域,计算HASH,以期找到一个好看的HASH(符合难度就叫好看),找到了就叫打包成功(也就是挖矿成功),赶紧广播出去。3d:每次收到广播来的区块,各节点检验该区块是否符合对区块的要求(至少HASH要好看嘛!),如果符合,就把此块保存下来,然后开始试图出下一个块(也即继续挖矿),把已经收到但尚未打包的交易打包进入下一个要出的块。

4、所有节点都在抢着打包,因为谁能正确打包谁就能得到BTC奖励。

4a:每成功出一个区块,打包者将会被奖励若干个BTC。最早一开始是奖励50个,每210000个区块(大约4年)奖励减半,所以后来是25个、12.5个、现在是6.25个,到2140年就会无币可挖。4b:事实上,矿工们除了可以得到系统的奖励,还能得到区块中的手续费。

5、每个节点收到区块后,如果验证无误,就接受该区块,将其附加到自己保存的区块链上。

5a:由于每个节点都和其他节点不断同步,所以每个节点(全功能节点)都保存着从第一个区块到现在这个区块的数据(目前已经产生将近70万个区块)。5b:一个区块的头部,会含有本区块体内全部交易的merkle根(其实也是一种HASH计算啦),如果区块体内的某个交易被篡改,可以通过计算merkle根,和头部的merkle根比较,从而发现篡改。5c:一个区块的头部,还会含有上个区块头部的HASH值(可以简称为区块的HASH)。这就可以校验上个区块是否完整、正确(因为任何数据差错,都做不出好看的HASH了)。你可以从最新的区块,一直追溯到创世区块(第一个区块),确保没有任何数据被改动过。

5d:整个区块链上,如果其中任何一个区块,有任何一点点的篡改,都会导致这个区块的HASH值不再是一个好看的HASH,也会导致其后区块的HASH都不再好看,任何明眼人,都会知道数据不对了。而每个好看的HASH,都是全球若干矿工,使用若干矿机,花着若干电费,辛辛苦苦挖出来的。一个试图篡改区块的人或组织,没有这么强大的能力。

结语

现在,你是不是了解了HASH,了解了挖矿,了解了区块链为什么这么能防篡改了呢!

我简单总结一下:

HASH很容易计算,但反过来倒推就不容易;输入有一点改变,输出就会大变;对于一个好的HASH算法,不同的输入,肯定会是不同的输出,不用担心碰撞;HASH值可以当作ID来看待;通过对比HASH,可以判断输入是否被人改了。

挖矿是为了给一个区块找一个好看的HASH,也即前面若干位是0的HASH;不管有多少节点在挖矿,都能够自动、简单地调整难度,使得保证大约10分钟才能找到一个好看的HASH;每个区块都将自己那个好看的HASH,放在下一个区块的头部;每个全节点都记录着所有区块的数据,而且可以很方便的验证所有区块没有被人改动过;如果有人想改历史区块里的数据,那要费老鼻子劲了!

不过这只是一大半,还有一些东西你是不了解的,也不是本文所想描述的。

你如果对其他的东西感兴趣,请留言。

文|卫剑钒


  1. https://www.zhihu.com/question/19743262/answer/289095984

  2. https://www.zhihu.com/question/56234281/answer/148349930

弄明白HASH,你就弄明白区块链的一大半相关推荐

  1. hash签名 java_java开发区块链只需150行代码

    原标题:java开发区块链只需150行代码 本文帮助你理解什么是区块链.将通过java开发区块链的实战学习方式,用 Java创建开发一个基本的区块链,实现简单的工作量证明系统.Java开发区块链的源代 ...

  2. 浅谈几种区块链网络攻击以及防御方案之51#37攻击

    旧博文,搬到 csdn 原文:http://rebootcat.com/2020/04/11/network_attack_of_blockchain_51_attack/ 写在前面的话 自比特币诞生 ...

  3. 【转】区块链是什么,如何简单易懂地介绍区块链?

    作者:知乎用户 链接:https://www.zhihu.com/question/37290469 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 友情提醒:比特币 ...

  4. 一分钟了解影响未来的技术-区块链(3):区块链的账户体系(二)

    前一篇我们对区块链的账户体系有了简单的理解,下面我们详细了解下账户保存与流转过程 我们都知道在银行开户,直接拿身份证,去银行柜台,或者在线上开一个账户就可以了,银行给我们一个账号,然后我们就可以针对这 ...

  5. 区块链是什么,如何简单易懂地介绍区块链

    作者:汪乐-LaiW3n 链接:https://www.zhihu.com/question/37290469/answer/107612456 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...

  6. 没用户、没技术,炒了这么久的区块链游戏似乎找到了一条新思路

    区块链已经火爆了大半年,这种全新分布式技术似乎和各行各业都可以结合,而当其瞄准了离钱最近的游戏业,"区块链游戏"这一新鲜名词应运而生,游戏从业者想必或多或少有所耳闻,但一知半解的也 ...

  7. 三点钟社群联合发起人Sky: 中国版“马克·扎克伯格”,用区块链激励差异化价值创造者...

    "区块链像什么?它就像一个荒芜的西部世界,大家重新在上面建设大楼.铺设道路-构建凝结着一群人共识的经济体.在这个动态全息的过程中,会形成千千万万种形态,而最终的不同则取决于创造生态的人是谁. ...

  8. 零时科技|2021年,你应该了解的区块链安全

    零时科技|2021年,你应该了解的区块链安全 市面上关于区块链安全的资料比较少,零时科技所做的项目基于传统网络攻防技术但又高于传统技术,既要能做代码审计,又需要有渗透测试的基本功,还需要有二进制和内核 ...

  9. 区块链钱包知识技术开发应用解决方案

    相信大家刚开始接触区块链的时候肯定会对区块链繁衍的概念给弄得云里雾里的,比如说区块链钱包啊,比特币呀,挖矿啊等等-接下来就由我来为大家讲解. 区块链钱包技术原理用一句话表示就是:钱包助记词(系统随机生 ...

最新文章

  1. Ymal格式转Properties格式
  2. ST-3806系列单圈编码器 测试说明
  3. Python过滤掉numpy.array中非nan数据
  4. 国际农产品交易模式 东亚模式对话国际农民丰收节贸易会
  5. 大数据热门职业薪酬榜 Hadoop人才居首
  6. 安卓应用自动化测试工具汇总
  7. eclipse主题下载网站
  8. ue4 怎么修改骨骼动画_【UE4】动画重定向
  9. c++ sleep函数_Linux 多线程应用中如何编写安全的信号处理函数
  10. java郝斌_郝斌Java自学教程全集打包
  11. repo同步代码_工欲善其事,必先利其器:repo 介绍
  12. thymleaf中枚举 判断对象值内容
  13. Python爬虫的经典多线程方式,生产者与消费者模型
  14. opencv中 .at<uchar>()和.ptr<uchar>()使用方法的区别
  15. 给table表格加斜线
  16. 用户自动设置报表格式
  17. 区块链对人工智能的变革:去中心化将带来数据新范式
  18. 《变形金刚2》剧情细节大揭秘(100%剧透!)
  19. C++实现简单的五子棋程序
  20. 为什么苹果电脑qq无法远程连接服务器,qq远程控制连接不上怎么回事(图示其原因和解决方案)...

热门文章

  1. 批量合并word文档
  2. PHP距离高考还剩多少天,今天距离2022年高考还有多少天
  3. 群体智能的未来趋势:网络安全领域、网络安全相关领域及其拓展
  4. 国际高中成绩差但是想读名校怎么办(文末附自救指南)
  5. 谷歌浏览器设置启动页被hao123劫持_win10系统打开chrome主页会被hao123劫持的故障原因及解决方法...
  6. Powermill汽车件模具五轴数控CNC编程视频教程
  7. html显示隐藏图片,简单的图片显示与隐藏
  8. Python基础学习笔记【廖雪峰】
  9. 提交模式窗口后,刷新父窗口数据+获取frameset中各模块中数据
  10. python vimdiff_vimdiff的常用命令