在生活中,我們需要用到隨機數的地方很多,例子也很好舉,比如我們買彩票的號碼就是一個隨機數。但是當計算機中需要產生隨機數的時候,絕大多數情況下並不是真的隨機數,我們把它稱為偽隨機數。這些偽隨機數是在一定的數值範圍內,採用一定的算法挑選出了一個數字,作為隨機產生的結果顯示出來,我們只能夠儘量讓這個算法公平一些,讓挑選到範圍內每一個數字的概率儘量做到一樣大,這樣產生的結果會更接近隨機數。
如果大家對編程有一些基礎的話,那麼對於rand()函數或者random()函數就不會陌生,這兩個函數都是用來產生偽隨機數的,要設定一個隨機種子(數值形式)來讓函數產生偽隨機數。雖然我們已經努力儘量讓產生的偽隨機數接近真實隨機數的概率,但是二者還是有本質區別的,最重要的一點區別是真實隨機數不能預測也沒有規律,而偽隨機數一定有規律(只是低級的規律好找,高級的規律不好找)而且可以被預測出來。
能夠被預測這件事對於計算機來說是比較可怕的,因為我們經常使用隨機數的場景是開獎之類的涉及利益和勝負的事情,如果生成偽隨機數那一部分的代碼被隱藏起來還好,遊戲的參與者看不到偽隨機數有什麼規律,也就無法人為操縱。但是針對一些代碼需要公開的情況,偽隨機數的規律性就變得很棘手。就像是最近比較火的區塊鏈技術,如果有人做了一個區塊鏈遊戲,他就不得不把代碼通過白皮書的形式發布出來,生成偽隨機數的部分一定會被玩家仔細研究。
之前有一個區塊鏈開獎的遊戲,玩家支付10元參與遊戲,當有10名玩家參與到遊戲中來的時候,就會隨機開出一個數字,生成區塊的時間跟這個數字最接近的玩家成為贏家,獲得10名玩家支付的一共100元獎勵。如果有人通過研究這個偽隨機數的產生規律,提前預知了下一個開獎數字是什麼,那麼他就可以操控自己在一個很接近的時間付錢進場生成區塊,那麼他就有很大的可能性獲得最後的勝利,得到一筆遠超過投入的財富。
所以偽隨機數在一些情況下不能奏效,我們還需要探索更科學更有效的方法來想辦法把需要公平的問題轉化成別的模式,但是在一些情境下,我們還是需要有偽隨機數來為我們進行一些工作的。我們有很多的算法可以產生偽隨機數,這些算法也各有優劣。最早的一個偽隨機數算法是1946年被計算機歷史上一個很重要也很著名的人——馮·諾依曼提出的平方取中法,選擇一個m位數Ni作為種子做平方運算,在這個數選中間m個位的數作為Ni+1。這個算法執行起來比較簡單,但是也存在著很大弊端,它能夠執行的周期很短,而我們通常認為周期越長隨機性能是越高的,而且如果選中了一些特殊的數字,比如100000,那麼平方的結果中間的m位將始終是000000。
我們也有一些方法來檢驗偽隨機數函數和發生器的隨機性能優劣,我們希望我們產生的偽隨機數具有均勻性,能夠接近真實隨機數各種可能的數值平等地擁有出現的機會,我們希望我們產生的偽隨機數具有獨立性,不能在多個偽隨機數之間產生內在聯繫從而讓別人分析得出偽隨機數產生的規律。但是歸根結底,計算機產生隨機數這件事可能就像是永動機一樣,以我們目前的水平難以完美實現,但是我們無法定論它一定無法實現。