白話解讀區塊鏈 二 超級難解的作業題——哈希函數

要了解比特幣以及區塊鏈技術,我們首先要學習的就是加密學方面的知識,現在我們要來認識一下區塊鏈技術中一個重要的知識點,哈希。

哈希,也叫作散列,他的功能是把任意長度的輸入,通過哈希演算法,變成固定長度的輸出,這個輸出的結果就是此輸入值的哈希值。哈希演算法也有很多不同的方式,我們以

sha256這種演算法作為例子,幫助大家了解哈希。

我們先選擇數字0,把它用sha256演算法進行計算,得到以下結果

5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9

我們得到了一個64位的字元串,這就是數字0的哈希值。為什麼是64位,因為sha256演算法的輸出結果是256位,所以才叫做sha256演算法,但是我們的輸出結果是用16進位表示,2進位的256位用16進位展示就是64位。

接下來我們再嘗試數字1000,得到的結果如下:

40510175845988f13f6162ed8526f0b09f73384467fa855e1e79b44a56562a58

接下來我們嘗試數字1001,得到的結果如下:

fe675fe7aaee830b6fed09b64e034f84dcbdaeb429d9cccd4ebb90e15af8dd71

接下來我們將一部電影文件做sha256(我們可以對任何文件做計算),得到的結果如下:

be2611986598002307b4b64bb5ba300d79efc8055d424a51ad6b252223eff27d

通過這幾次嘗試,我們可以總結出以下幾種哈希函數的特點:

第一,固定長度的輸出,不論輸入值是只有一位數的0,或者輸入值遠遠大於64位的一部電影,我們得到的輸出永遠都是64位(僅限sha256演算法,其他哈希演算法有不同的輸出位數)。

第二,輸入不同,得到的輸出也不同,並且即使輸入值的改變很小,得到的輸出值也會有很大的變化,1000和1001之間之變化了一點點,但是得到的哈希輸出值千差萬別,我們也可以叫這種現象為雪崩效應。

第三,單向性,從對應的輸出中,我們很難計算出輸入值是什麼。

對於第二個特點,我們可能會有些疑問,既然哈希輸入值可以為任意數值,而輸出卻只是固定的256位,那麼輸入值的集合一定會大於輸出值的集合,這樣的話,一定存在兩個輸入值計算哈希以後得到相同的輸出值,這種情況我們稱之為「碰撞」,一個合格的加密函數,必須要避免碰撞的發生,即具有「碰撞阻力」。那麼對於sha256演算法,因為它的輸出值是固定的256位,那麼這個演算法的所有輸出值一共只有2256個,運氣最差的情況下,只要我們隨便找到2256+1個輸入值,並且計算sha256,那麼就必定有一個輸出值對應了兩個不同的輸入值,實際上我們平均只需要做2128次左右的計算,就大概率可以找到碰撞了,那麼是不是說sha256這種演算法就不具備碰撞阻力呢?也不一定,雖然它存在碰撞的可能性,但是不代表我們能夠找得到,就像那句話說的「不管遠近,只要是到不了的地方,都叫遠方」。同理,找不到的碰撞,那就算沒有碰撞。因為2128是一個非常非常大的數字,大到遠遠超過了我們人類所能理解的範疇,即使我們把人類歷史上所有的計算機全部集合起來,從宇宙誕生的那一刻起就不停的在計算sha256,一直到今天為止,我們找到碰撞的概率依然接近於0。現在我們可以放心的承認,sha256演算法具有碰撞阻力,是一個合格的加密函數了,不過這也只是目前的結果,說不定哪一天人類科技進一步發展,sha256也避免不了被破解的命運,要知道它的許多前輩,MD4,MD5等都是曾經安全的演算法,但是時至今日已經被宣布破解。

由於哈希函數具有以上幾項特點,我們在實際生活中可以利用哈希做許多事情。例如,我們可以用哈希函數當做文件的「摘要」,例如小明上傳了自己的一份作業到網上,等到某一天他又將作業下載到自己的電腦中,但是小明擔心自己的作業被黑客篡改過,並且作業中的內容又很多,他無法記住所有內容也沒有精力一頁一頁去核對,這時候小明只需要在上傳文件之前,將整個文件做哈希運算,保存下哈希值,等到再次下載以後,對新下載的文件也做哈希運算,將得到的哈希值與之前保存的做對比,如果一致,那就說明這兩份文件是相同的。

說了這麼多關於哈希演算法的特性,我們來看一下它在比特幣中的一處應用,我們之所以用sha256來舉例,就是因為在比特幣中,大量使用的哈希函數就是sha256。還記得上篇文章的示例嗎?在班級裡面,同學們都在做「作業題」,解出作業題的小夥伴就可以得到獎勵。實際上,作業題中最難解的部分,就是在做哈希計算,比特幣的特點就是,當你計算的哈希次數越多,你就越有可能得到比特幣獎勵,這就是挖礦的過程。這種特性也叫作工作量證明(prof of work,簡寫POW),也有其他的數字貨幣使用不同的方式獎勵挖礦的人員,我們在以後的文章中會講到。

我們來具體看一下比特幣是如何運行這一模式的,為了能讓挖礦的機器計算足夠多的哈希運算,比特幣規定了一個哈希運算的輸出區間,這個區間相對於整個sha256的輸出空間來說是比較小的,在每次機器計算sha256演算法以後,除非計算的結果正好落在規定的區間以內,否則此次計算就是失敗的,需要改變一個輸入值再重新計算。至於計算的難度,是根據目前的全網算力決定的,比特幣每兩周調整一次難度,使得最終的結果符合平均每十分鐘計算正確一次。這些都是比特幣自身的特點。我們舉個簡單的例子,可能某一次的計算中,輸出的結果規定為00000000000000000000000000000000000000000000004ebb90000000000,要知道sha256的輸出結果其實就是一段16進位表示的數字,那麼我就可以規定計算出來的結果要小於上述的sha256值。也就是說,正確的輸出結果必須落在以下區間:

(0,00000000000000000000000000000000000000000000004ebb90000000000),而想要挖礦的人們,除了一次又一次的變換輸入值進行計算嘗試意外,沒有什麼其他的辦法,這就註定了同學們解的這些作業題是超級困難的。

你可能會喜歡