電腦隨機數是如何生成的?

2021-07-09 03:14:12 字數 3144 閱讀 9712

電腦產生的隨機數稱為偽隨機數,是通過演算法模擬的,看上去和隨機數一樣,實際上能算出來的數就是可以預見的數(對你來說不可預見,對電腦則是可預見),不是真正的隨機數。
對計算機沒有研究,一直不知道計算機是如何生成隨機數的。只是知道計算機做的一切事情都是按照程式來的,人們讓它們做什麼它們才做什麼。同樣的計算,給計算機來算,兩次得到的肯定是同樣的結果。那麼隨機數是如何生成的?

中學從教科書上知道,有隨機數表,計算機出現後,大多用計算機來生成隨機數。從那時候開始,我就一直想知道這個問題的答案。

從乙個大數「種子」開始重複某種迭代計算,通常是加減乘除加求餘,種子可以取系統時間,因為使用者不可能精確到微秒控制程式執行,就基本保證了每次生成數值的順序不同

一般來說如果用數位電路產生的都是偽隨機數,但由於迴圈時間太長可視為隨機數。而現在有用模擬電路產生的隨機數,主要原理是將熱雜訊放大,然後編碼~~

**:最近瀏覽「程式設計師論壇」時發現不少好帖,增長了不少知識,現拿其中一則為例與大家共同分享心得。

某人提出乙個問題:怎樣才能生成一億個不重複的隨機數?

問題表述起來很簡單,似乎只要弄明白什麼叫隨機數以及怎樣用電腦生成隨機數,就能解決問題。

隨機數,個人理解為一定範圍內出現的毫無規律的數,比如扔乙個骰子,落在桌面上時朝上的一面所表示的數就是隨機數,這個數只能在1到6的範圍內,但具體是什麼數,誰也不能肯定,因為它沒有規律。一組不重複的隨機數,對扔骰子來說就是扔出六個不一樣的數來,再比如洗一次撲克牌,洗完後就是54張不重複的隨機數。

第二個問題,怎麼樣用電腦生成隨機數?只要呼叫某個語言的某個函式即可。其實電腦是沒辦法生成真正的隨機數,因為電腦是高度有規律的機器,讓它生成乙個沒規律的數,根本辦不到。平時程式設計師用某個函式生成的隨機數,只是利用某個演算法弄出來的偽隨機數,看起來像,其實不是,能解決問題就行。

回到這個帖子所描述的問題上來。生成一億個不重複的隨機數,最直接的演算法就是每用函式生成乙個數,就把它放在乙個筐裡,第乙個數直接放到筐裡,以後生成的數在放到筐裡之前和筐裡的每乙個數比較一番,一旦發現筐裡有和新生成的數一樣的數時,丟掉這個新生成的數,再接著生成數。

毫無疑問,這種演算法的效率非常低,看看其中的比較次數就知道了,最差的次數趨於無窮次。也就是說到後來,幾乎生成不了和以往不同的數。

當然還可以將這個演算法公升級為效率高得多的演算法,每生成乙個數,把這個數從隨機數生成器取的範圍中去掉,比如要生成10個隨機數,第一次生成乙個3,我把3從隨機數的範圍中去掉,第二次只從1到9這個範圍內找。3對應4,4對應5……9對應10。這樣就不存在比較的環節,然而又多出乙個對應的環節,每生成乙個數之後就要把剩下的數重新對應一遍,效率也不容樂觀。

目前以我為代表的普通程式設計師的想象力也就到此為止,想不出什麼高階解決辦法,就當扔一塊磚頭出來,下面就把真正的碧玉——數學家級程式設計師的演算法隆重介紹請出來。

我們先用另一種眼光來看不重複的隨機數:加密。把乙個能看懂的英文本串打亂字母的順序,變成不可讀,這就是加密。但必須得有規律地打亂,字母a對應另外乙個固定的字母ax,字母b對應另外乙個固定的字母bx,以此類推,而且必須一一對應的。那麼字串「ab…z」這26個字母對應的26個加密字母「axbx和zx」就可以看成是對應範圍a到z的不重複的偽隨機數,這就是數學家的演算法的**。

看看回帖者的原文:

「可以採用32bit rsa演算法

設a從2~(n-1)

c=(a exp d) mod n

滿足如下條件:

d是素數,n是兩個素數(p,q)之積,

(d * e) mod ((p-1) * (q-1))=1

因為:若

c=(a exp d)mod n

有: a=(c exp e) mod n

所以,c與a 一一對應。

所以,對於a=2~(n-1),有不重複,無遺漏的偽隨機碼c。」

凡是稍微扯上一點數學,尤其是高等數學的問題,我等泛泛之輩看起來就有點費勁,這裡雖然文字不長,但是還得慢慢來看。

這裡面rsa演算法是密碼學三大演算法之一(rsa、md5、des),是一種不對稱密碼演算法。說如果滿足條件:d是素數,n是兩個素數(p,q)之積,(d * e) mod ((p-1) * (q-1))=1,那麼存在c與a(範圍從2到n-1)一一對應,且c=(a exp d)mod n。a是乙個有順序的數,c就是乙個看似無規律的偽隨機數。mod運算表示求模,例如7mod3=1。意思是7除以3餘1。類似地8mod3=2,9mod3=0。exp表示前面數的後面數次方,aexpd表示a的d次方。這兩個運算清楚了,其它的也就沒什麼困難的了,*是乘法的意思,大多數理科生都清楚。

搜了一下網路,還得加上一些條件,1,p和q不能一樣。2,e<(p-1)(q-1)且e與(p-1)(q-1)的最大公因數為1。

下面用乙個例子來試驗一下,看看這個演算法有多神奇。

設n=15,p=5,q=3,則a為2到14的數。現在要產生2到14的偽隨機數。取d為3,e為3,

c2=(2exp3)mod15 = 8,  

c3=(3exp3)mod 15 = 12,

c4  = (4exp3)mod 15= 4,

c5  = (5exp3)mod 15= 5,

c6  = (6exp3)mod 15= 6,

c7  = (7exp3)mod 15= 13,

c8  = (8exp3)mod 15= 2,

c9  = (9exp3)mod 15= 9,

c10  = (10exp3)mod 15= 10,

c11  = (11exp3)mod 15= 11,

c12  = (12exp3)mod 15= 3,

c13  = (13exp3)mod 15= 7,

c14  = (14exp3)mod 15= 14。

比較完美,如果數再大一點,可能看起來更隨機一些。

由這個演算法產生的1億的偽隨機數,效率那可是相當的高,只不過運算時要用到大數運算庫。在一些講求效率的場合應用的話,再做一些對應上的處理,公升級一下演算法,那定是相當的完美。

由此可以看出,演算法的優化,如果僅僅停留在大腦能夠想象到的小學數學的階段,那是遠遠達不到要求。乙個優秀的程式設計師,還需要加深對離散數學的理解,雖然,這次提到的演算法已經深入到了數論的層次上了,但是rsa演算法已經是應用非常廣泛的演算法,對其稍加變通,便可以發揮出更加不可思議的作用。程式設計師還是需要多學習演算法,多學習數學,才能發揮出超出一般程式設計師的不可思議的能力。

Python如何生成隨機數?

python中,獲取隨機數的方法大致有如下 import random 匯入random python中利用random獲取乙個0到1的隨機浮點數 a random.random print a 列印結果 python中利用random獲取一定範圍內的 10到20 隨機浮點數 b random.un...

Swift 如何生成隨機數

var numberone int int arc4random print numberone 結果 3628967563說明 arc4random 直接返回uint32型別資料 var numberfour double drand48 print numberfour 結果 0.3964647...

c 如何生成隨機數

使用rand 函式 標頭檔案 1 如果你只要產生隨機數而不需要設定範圍的話,你只要用rand 就可以了 rand 會返回一隨機數值,範圍在0至rand max 間。rand max定義在stdlib.h,其值為2147483647。例如 include includevoid main 2 如果你要...