1. 程式人生 > >C語言真正獲取隨機數

C語言真正獲取隨機數

問題1:怎樣獲得一個真正的隨機數?要知道,rand()是不能產生真正的隨機數的!即使不能產生真正的隨機數,也要大概接近呀!而rand()好象每次的隨機都一樣。

專家解答:

之所以rand()每次的隨機數都一樣是因為rand()函式使用不正確。各種程式語言返回的隨機數(確切地說是偽隨機數)實際上都是根據遞推公式計算的一組數值,當序列足夠長,這組數值近似滿足均勻分佈。如果計算偽隨機序列的初始數值(稱為種子)相同,則計算出來的偽隨機序列就是完全相同的。這個特性被有的軟體利用於加密和解密。加密時,可以用某個種子數生成一個偽隨機序列並對資料進行處理;解密時,再利用種子數生成一個偽隨機序列並對加密資料進行還原。這樣,對於不知道種子數的人要想解密就需要多費些事了。當然,這種完全相同的序列對於你來說是非常糟糕的。要解決這個問題,需要在每次產生隨機序列前,先指定不同的種子,這樣計算出來的隨機序列就不會完全相同了。你可以在呼叫rand()函式之前呼叫srand((unsigned)time( NULL )),這樣以time函式值(即當前時間)作為種子數,因為兩次呼叫rand函式的時間通常是不同的,這樣就可以保證隨機性了。你也可以使用srand函式來人為指定種子數。Windows9x/NT的遊戲FreeCell就允許使用者指定種子數,這樣使用者如果一次遊戲沒有成功,下次還可以以同樣的發牌結果再玩一次。

問題2:我按照上述方法並不能產生隨機數,僅產生公差為3或4的等差數列:
#include <stdlib.h>
#include <iostream.h>
#include <conio.h>
#include <time.h>
void main()
{
for(int i=0;i<100000;i++)
{
srand( (unsigned)time( NULL ) );
cout<<rand()<<endl;
}
}
專家解答:
你的程式是有問題的,你每產生一個隨機數之前,都呼叫一次srand,而由於計算機執行很快,所以你每次用time得到的時間都是一樣的(time的時間精度較低,只有55ms)。這樣相當於使用同一個種子產生隨機序列,所以產生的隨機數總是相同的。你應該把srand放在迴圈外:
srand( (unsigned)time( NULL ) );
for(int i=0;i<100000;i++)
{
//相關語句
}

C語言生成隨機數需要用到兩個函式,一個是srand(),一個是rand(),首先給srand()提供一個種子,unsignedint型別,其取值範圍從0~65535,srand()根據這個種子會由一個特定的公式生成一個隨機數序列;然後呼叫rand(),它會依次從這個序列中返回一個數(在0到32767之間),而在不指定srand()種子的情況下,它每次都使用預設的種子,因此生成的序列是同一個,你每次執行,當然就取到相同的數字了。

你可以在程式裡新增標頭檔案time.h,用當前時間作為srand的種子,這樣就能保證每次執行時都能取到不同的隨機數序列。如下:
time_t t;
srand((unsigned) time(&t));
然後就可以用rand()取隨機數了