偽隨機與實驗

2021-09-01 16:16:32 字數 2109 閱讀 3033

眾所周知,計算機產生的是偽隨機數。所謂偽隨機,就是:當知道種子和隨機產生演算法之後,就可以完全確定出隨機數序列了。並且這個隨機數序列是迴圈重複的。不同的隨機產生演算法的迴圈週期不同;好的隨機產生演算法的迴圈週期會很長。

有的文章提到,可以通過引入系統以外的變數來達到真隨機的目的,比如「unix 維護了乙個熵池,不斷收集非確定性的裝置事件,即機器執行環境中產生的硬體噪音,來作為種子」。個人覺得,這本質上仍然是偽隨機,只是利用硬體雜訊生成種子而已,這和使用時間戳作為種子沒有本質區別。只是別人可能沒法知道種子是啥,因此也無法推測出隨機序列。而該文中提到的 /dev/random (其實還有乙個 /dev/urandom)是乙個字元檔案,如果讀取它,會取得隨機字元,而不是隨機數字。當然我們可以想辦法把隨機字元轉換成隨機數字。關於如何使用 /dev/random 和 /dev/urandom, 可以參見這篇文章,本文不再贅述。

先看**:

#include #include #include using namespace std;

void gen_rand_int(unsigned int seed)

void gen_2_rand_int(unsigned int seed)

cout << "the first number is: " << i_1 << endl;

cout << "the 65536" << " number is " << i_65536 << endl;

cout << "the 65537" << " number is " << i_65537 << endl;

cout << "the " << max_unsigned_int+1 << " number is " << i_max_ui << endl;

cout << "the " << max_unsigned_int+2 << " number is " << rand() << endl;

}int main()

然後,給出觀察結論:

1. 在某一台機器上,由main函式中連續2次呼叫 gen_rand_int(10) 的列印結果完全一致。

仍然在這一台機器上,多次執行該二進位制可執行檔案,gen_rand_int(10)的列印結果完全一致。

由此可以看出,偽隨機的含義就是,一旦知道了種子和演算法,隨機數序列就是確定的了。這一點在下面還可以繼續看出。

2. 筆者將以上程式拿到5臺機器上跑,在相同的種子下,結果很有趣:

前10個數

第65536個數

第65537個數

第2^32個數

第2^32+1個數

a - ubuntu 18.04

abcd相同

1174608988

每次都變

1843318998

1902554484

b - ubuntu 16.04

abcd相同

1174608988

每次都變

1843318998

1902554484

c - centos 7.3

abcd相同

1174608988

01843318998

1902554484

d - rhel 7.5

abcd相同

1174608988

01843318998

1902554484

e - cygwin on windows

與abcd不同

與abcd不同

0與abcd不同

與abcd不同

由上可以看出,

a.一般來說,在給定種子時,在各linux系統上c++程式取得的隨機數序列基本都是一致的;

b.第65537個隨機數似乎比較特別,ubuntu每次跑都會是乙個不同的值,似乎有點「隨機」,而red hat系列的linux此處總為0

c. cygwin系統的隨機數取得與真實linux系統的隨機數差別較大,可能是取隨機數的庫使用的是windows上的庫。

d. 沒有看出來迴圈週期是多少,但基本可以確定不是65536或2^32;根據網上有些文章,可能採用的是一種較好的隨機生成演算法,其迴圈週期遠大於2^32. 

(完)

的確是偽隨機

c語言的 裡 rand 函式可以產生 0 rand max 包括 之間的隨機數,通常是經過 srand 函式進行初始化後再使用。rand max 的值預設是 32767 即 2 15 1 在 裡的定義是 define rand max 0x7fff 所以如果需要求 a,b 顯然要有 b rand m...

偽隨機演算法同步

一般來說網遊要求邏輯在服務端計算,原因是一方面利於玩家之間邏輯同步的實現,另一方面伺服器做仲裁方,防止玩家作弊。但在有些情況下,由於一些邏輯要求的實時性很高,我們不得不把一些邏輯的判斷放在客戶端,以保證遊戲的流暢感。比如動作遊戲中,玩家受擊時的動作切換,如果需要根據屬性邏輯計算的結果切換到不同被動動...

概率演算法 偽隨機數生成 拋硬幣實驗

概率演算法 偽隨機數生成 拋硬幣實驗 實驗平台 vc net 2003 建乙個 win32控制台程式 偽隨機數生成的原理 隨機數在概率演算法中扮演著十分重要的角色。在現實計算機上無法產生真正的隨機數,因此在概率演算法中使用的隨機數都是一定程度上隨機的,即偽隨機數。產生偽隨機數最常用的方法是線性同餘法...