random 隨機數的產生方式與原理

2021-08-10 18:08:55 字數 2043 閱讀 2448

計算機中的隨機數都是偽隨機數

下面看這樣乙個c程式:

// rand_1.cpp

#include static unsigned int rand_seed;

unsigned int random(void)

void random_start(void)

void main()

它完整地闡述了隨機數產生的過程:

首先,movedata(0x0040,0x006c,fp_seg(temp),fp_off(temp),4);

這個函式用來移動記憶體資料,其中fp_seg(far pointer to segment)是取temp陣列段位址的函式,fp_off(far pointer to offset)是取temp陣列相對位址的函式,movedata函式的作用是把位於0040:006ch儲存單元中的雙字放到陣列temp的宣告的兩個儲存單元中。這樣可以通過temp陣列把0040:006ch處的乙個16位的數送給rand_seed。

其次,rand_seed=(rand_seed*123+59)%65536;

是用來計算隨機數的方法,隨機數的計算方法在不同的計算機中是不同的,即使在相同的計算機中安裝的不同的作業系統中也是不同的。我在linux和windows下分別試過,相同的隨機種子在這兩種作業系統中生成的隨機數是不同的,這說明它們的計算方法不同。

然後,movedata(0x0040,0x006c,fp_seg(temp),fp_off(temp),4);

隨機種子為什麼要在記憶體的0040:006ch處取?0040:006ch處存放的是什麼?

學過《計算機組成原理與接**術》這門課的人可能會記得在編制rom bios時鐘中斷服務程式時會用到intel 8253定時/計數器,它與intel 8259中斷晶元的通訊使得中斷服務程式得以運轉,主機板每秒產生的18.2次中斷正是處理器根據定時/記數器值控制中斷晶元產生的。在我們計算機的主機板上都會有這樣乙個定時/記數器用來計算當前系統時間,每過乙個時鐘訊號週期都會使記數器加一,而這個記數器的值存放在哪兒呢?沒錯,就在記憶體的0040:006ch處,其實這一段記憶體空間是這樣定義的:

timer_low dw ? ;位址為 0040:006ch

timer_high dw ? ;位址為 0040:006eh

timer_oft db ? ;位址為 0040:0070h

時鐘中斷服務程式中,每當timer_low轉滿時,此時,記數器也會轉滿,記數器的值歸零,即timer_low處的16位二進位制歸零,而timer_high加一。rand01.c中的

movedata(0x0040,0x006c,fp_seg(temp),fp_off(temp),4);

正是把timer_low和timer_high兩個16位二進位制數放進temp陣列,再送往rand_seed,從而獲得了「隨機種子」。

現在,可以確定的一點是,隨機種子來自系統時鐘,確切地說,是來自計算機主機板上的定時/計數器在記憶體中的記數值。

en...沒有最後。。lvl--

再看一段**:

//rand_2.cpp

#include #include using namespace std;

int main()

{ srand((unsigned)time(null));

unsigned int r=rand();

cout<<"r = "<

這裡使用者和其他程式沒有設定隨機種子,則使用系統定時/計數器的值做為隨機種子,所以,在相同的平台環境下,編譯生成exe後,每次執行它,顯示的隨機數會是偽隨機數,即每次執行顯示的結果會有不同。

總結

隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那麼產生的隨機數就不會變。在相同的平台環境下,編譯生成exe後,每次執行它,顯示的隨機數都是一樣的。這是因為在相同的編譯平台環境下,由隨機種子生成隨機數的計算方法都是一樣的,再加上隨機種子一樣,所以產生的隨機數就是一樣的。

只要使用者或第三方不設定隨機種子,那麼在預設情況下隨機種子來自系統時鐘(即定時/計數器的值)

Random 產生隨機數

幾乎模組中所有函式都依賴於基本函式random 它在半開放範圍 0.0,1.0 內產生乙個統一的隨機浮點數。1.基本使用 var num parseint math.random 10 取0到10之間的整數 但不包括10 2.在指定範圍內產生多個不同的隨機數 var num parseint mat...

Random產生隨機數問題

昨天在開發時發現這個問題,在同乙個for迴圈內,通過random多次產生隨機數得到的隨機數竟是一樣的!以前還真沒發現這個問題。以下是簡化的 如果將random定義在for迴圈外面則不會有問題 猜測random與時間有關且存在固定的演算法獲取隨機數 但實際開發中一般會把產生隨機數封裝為乙個方法,呼叫的...

linux產生隨機數的方式

root localhost echo random 22658random的隨機數範圍為0 32767,可以通過在輸出的隨機數後增加字串的方式,最後再一起執行md5sum操作並擷取結果的後n位。root localhost echo test random md5sum 8b2e15402190b...