用偽隨機數建造真的

2021-04-12 16:53:21 字數 2422 閱讀 5703

「應用密碼學」作者bruce schneier 對隨機序列的定義是:

(1)看起來像隨機數

(2)不可**

(3)不可重複產生

隨機數由性質相同的數組成,單個或幾個數不能說是隨機數。所以一般又叫隨機數組。它們有一些有趣的性質:隨機數加、減、乘常數後還是隨機數,自行相加、相減、相乘後還是隨機數,對隨機數組作有規律的變換絲毫不能改變它,就是說變來變去還是隨機數組。

加密解密就是利用隨機數加、鹼、乘常數後還是隨機數的性質而實現的,它可以吞沒數字和釋放數字。

什麼是看起來像隨機數,肯定是雜亂無章的,如果看到明顯的規律那肯定不是隨機數,一般說的好的隨機數,應該是分布均勻的,體現在陣列的代數和的平均值接近陣列的最大值除以2,且陣列越大越明顯,但任取一小段肯定是不均勻的。它們服從統計規律,可以通過統計來分析它們。

不可**和不可重複產生是相關的,能重複產生就可以**,自然界裡「陣列」的乙個例子,就是圓周率的小數尾數,它分布均勻,沒有週期,無窮無盡,如果我們只知陣列不知**可以將它作為1位10進製隨機數組,但知道**它就是可以重複產生,可以**的,就不能作為隨機數組,看來隨機數組是有相對性的。所有隨機函式都只能產生偽隨機數組,就象我們使用隨機函式產生陣列,如果在其週期之內使用,並隱藏其發生方法,則在我們這裡陣列是不隨機的,如果破解者搞不清資料的來歷,那在他那裡就是隨機的,這樣就夠了。但是我們仍不放心,因為他們有復現隨機數組的可能性。例如你使用隨機數函式並隱藏了種子,破解者只要知道你用的函式就夠了,他也許可以做出整個週期的陣列,並利用陣列攻擊你,那時你用什麼種子也沒有用,但實際上,如果週期很長,他用高速計算機搞到老也不可能查完一遍週期內的數值,這種假的跟真的也差不多。對一般使用者來說是真隨機數還不夠,要對破解者也是才行。

真隨機數的產生是很容易的,乙個骰子(色子)就是個6進製陣列發生器,在6個面上標記0、1、2、3、4、5,投一次記乙個數,6進製陣列就這樣產生了。如果有十個面,就可以得出10進製數了,這裡必須有人做一些運動,才能完成這個過程。可否用計算機來模擬這個過程?計算機這種嚴格按運算邏輯的東西行嗎?讓我們來設法實現它。

真隨機數組的產生:

我們模擬骰子(色子)來產生 6進製陣列,例如做600個數的隨機數組,先建乙個有序陣列它是這樣排列的,0、1、2、3、4、5、0、1、2、3、...... 一共600個數,也就是sz[0]......sz[599]。在此範圍內我們隨機抽取兩個sz[i] 和 sz[j],讓它們的數值交換,當這個過程做的足夠多時,陣列就變成隨機數組了。交換的次數少了不行,有的地方可能還沒有觸及,那就會有原來規律性的殘餘,如何判斷呢?例如你可以做圖,以序列號為 x,數值為 y,開始時圖形為公升序的三角波形,當變成無規律的雜亂波形時就可以了,如果是人為的,現在已經完成任務了。如何用計算機來完成?還是借助隨機函式吧,使用時間(執行時間、系統時間)相關的數做種子,讓它產生0到599之內的隨機數,用它們作序列號,做數值交換,直到變得雜亂無章,以陣列長度為週期,產生隨機數並作交換,算作一次處理。做幾個按鈕,每個按鈕對應一種隨機函式處理一次,還有一些按鈕對應著有規律變換,例如原排列是1、2、3、1、2、3......,變成3、1、2、3、1、2......就是一種有規律變換,恰當使用也可以加速融合。現在你隨便去按這些按鈕吧,真隨機數就這樣產生了。

隨機數組的檢驗:

什麼時候交換是個頭啊?可以通過檢驗判斷。方法眾多僅舉一例:測量兩個相同元素相繼出現的機率,顯然是1/6,乘以600得到10,也就是兩個相同元素相繼出現的次數應該在10附近,到時候再多操作也只能使出現的次數在10附近左右擺動,這說明陣列已經均勻了,或者說均勻度已經飽和了,再做下去已經沒有意義了。

再進一步,由時間作種子的隨機函式,給按鈕隨意排序,並控制去按這些按鈕,執行不同操作方案,直到檢測合格為止,你就可以坐享其成了。

儘管上面「隨機抽取兩個序號使它們的數值交換」是用隨機函式來完成的。但也不可能使陣列向有序化發展,這裡一種自然規律在起作用,就是「熵增加原理」,自然作用下有序向無序發展是不可逆的過程,例如你整天洗紙牌,也不可能有一天發現是順序的了,墨水滴倒水盆裡會逐漸擴散,而再也沒有機會聚成一滴了。所以我們用不可預料的數作種子,開動幾個隨機函式去攪動陣列的序列也是不可逆的,由於排序是多種因素決定的,所以要想重複實現是不可能的,例如,按了哪些按鈕、多少次、順序如何、時間間隔如何等。這樣就保證了陣列的隨機性。這個過程是不可再現的,計算機作為多工系統,不能保證同一段程式執行時間精密一致,也就是說與計算機本身的狀態有關,而執行時間又關係到其它種子的數值,所以是不可復現的。

隨機函式如果效能不好,將使效率降低,甚至不能將有序陣列變為無序,尤其不要讓陣列長度大於隨機函式的週期,如果遇到這樣的情況,可以在適當的位置,重新設定種子值。這個方法也是檢驗隨機函式的利器。這裡生成的隨機數組是一種可以更新的資源,用過以後再作交換則可以成為全新的。

將此種方法命名為《序列數交換法》。希望對需要用真隨機數的朋友有幫助。

但是真隨機數並不一定便於應用,還是自己控制隨機函式種子好些,只要你加入些不確定因素即可,你可以使用密碼來控制種子的數值,而密碼是執行後輸入的,根本不出現在沒有執行的程式裡,這樣對你來說陣列是偽隨機數組,但在破解者那裡就是真隨機數組了,這樣的隨機數組可以稱為單向真隨機數組吧。

隨機數 偽隨機數

隨機數 偽隨機數 rand函式在產生隨機數前,需要系統提供的生成偽隨機數序列的種子,rand根據這個種子的值產生一系列隨機數。如果系統提供的種子沒有變化,每次呼叫rand函式生成的偽隨機數序列都是一樣的。srand unsigned seed 通過引數seed改變系統提供的種子值,從而可以使得每次呼...

隨機數生成 偽隨機數和真隨機數

c語言隨機數的生成,很隨機,又不隨機,比如像下面的程式 c語言生成隨機數的函式在stdlib.h庫中 include includeint main return 0 上面的 經過執行生成了 41 18467 6334 26500但是無論執行多好遍結果都是一樣的,隨機數並不隨機。這是因為rand 函...

隨機數 科普 真隨機數和偽隨機數

位元幣使用者很喜歡討論 非對稱加密 橢圓曲線 量子計算機 這類高深莫測的話題,然後再以一種非常莫名其妙的方式把幣弄丟,比如說 隨機 隨機很重要,對於位元幣這種密碼學電子貨幣來說,尤其重要。可惜社群內對於隨機的討論並不多,導致很多人缺乏正確的認識,因此,我們今天就和大家聊聊隨機。說到隨機,有兩個必須要...