導航:首頁 > 編程系統 > linux下生成隨機數

linux下生成隨機數

發布時間:2024-04-07 06:06:09

1. 急:在linux內核中如何產生一個隨機數

linux內核自1.3.30版本以來實現了一個隨機數產生器,從理論上說它能產生真正的隨機數,該隨機數產生器是從設備驅動收集電路上的環境噪音放入熵池,它的實現代碼在drivers/char/random.c中,自己去看吧

2. 使用/dev/random生成隨機整數

很多庫常式產生的「隨機」數是准備用於模擬、游戲等等;它們在被用於密鑰生成一類的安全函數時是不夠隨機的。其問題在於這些庫常式使用的演算法的未來值可以被攻擊者輕易地推導出來(雖然看起來它們可能是隨機的)。對於安全函數,需要的隨機值應該是基於量子效應之類的確實無法預測的值。Linux內核(1.3.30以上)包括了一個隨機數發生器/dev/random,對於很多安全目的是足夠的。

/dev/random 是如何創建隨機數的呢?

Linux 操作系統提供本質上隨機(或者至少具有強烈隨機性的部件)的庫數據。這些數據通常來自於設備驅動程序。例如,鍵盤驅動程序收集兩個按鍵之間時間的信息,然後將這個環境雜訊填入隨機數發生器庫。

隨機數據存儲在 熵池中,它在每次有新數據進入時進行「攪拌」。這種攪拌實際上是一種數學轉換,幫助提高隨機性。當數據添加到熵池中後,系統估計獲得了多少真正隨機位。

測定隨機性的總量是很重要的。問題是某些量往往比起先考慮時看上去的隨機性小。例如,添加表示自從上次按鍵盤以來秒數的 32 位數實際上並沒有提供新的 32 位隨機信息,因為大多數按鍵都是很接近的。

從 /dev/random 中讀取位元組後,熵池就使用 MD5 演算法進行密碼散列,該散列中的各個位元組被轉換成數字,然後返回。

如果在熵池中沒有可用的隨機性位, /dev/random 在池中有足夠的隨機性之前等待,不返回結果。這意味著如果使用 /dev/random 來產生許多隨機數,就會發現它太慢了,不夠實用。我們經常看到 /dev/random 生成幾十位元組的數據,然後在許多秒內都不產生結果。

幸運的是有熵池的另一個介面可以繞過這個限制:/dev/urandom。即使熵池中沒有隨機性可用,這個替代設備也總是返回隨機數。如果您取出許多數而不給熵池足夠的時間重新充滿,就再也不能獲得各種來源的合用熵的好處了;但您仍可以從熵池的 MD5 散列中獲得非常好的隨機數!這種方式的問題是,如果有任何人破解了 MD5 演算法,並通過查看輸出了解到有關散列輸入的信息,那麼您的數就會立刻變得完全可預料。大多數專家都認為這種分析從計算角度來講是不可行的。然而,仍然認為 /dev/urandom 比 /dev/random 要「不安全一些」(並通常值得懷疑)。

應用中出現的問題:

在我們的伺服器程序中,用戶登陸的時候會讀取/dev/random產生隨機數,問題來了,當用戶登陸比較密集,這時候read就會返回特別慢,並且返回的位元組數也比要求的少,甚至不返回――阻塞。我們把用戶登陸處理函數放在了線程池裡,導致的問題就是線程池裡所有線程都可能會阻塞,這就造成了拒絕服務攻擊。導致其他用戶登陸失敗。

解決方案:

CODE:1 #include <stdio.h>

2 #include <string.h>

3 #include <sys/types.h>

4 #include <sys/stat.h>

5 #include <sys/file.h>

6 #include <sys/time.h>

7 #include <errno.h>

8 #include <unistd.h>

9 #include <stdlib.h>

10

11 static int get_random_fd (void)

12 {

13 static int fd = -2;

14

15 if (fd == -2)

16 {

17 fd = open ("/dev/random", O_RDONLY | O_NONBLOCK);

18 if (fd == -1)

19 fd = open ("/dev/urandom", O_RDONLY | O_NONBLOCK);

20 }

21

22 return fd;

23 }

24

25 /*

26 * Generate a series of random bytes. Use /dev/random if possible,

27 * and if not, use /dev/urandom.

28 */

29 void get_random_bytes(void* buf, int nbytes)

30 {

31 int i, fd = get_random_fd();

32 int lose_counter = 0;

33 char *cp = (char*)buf;

34 struct timeval tv;

35 static unsigned seed = 0;

36

37 if (fd >= 0)

38 {

39 while (nbytes > 0)

40 {

41 i = read (fd, cp, nbytes);

42 if ((i < 0) &&

43 ((errno == EINTR) || (errno == EAGAIN)))

44 continue;

45

46 if (i <= 0)

47 {

48 if (lose_counter++ == 8)

49 break;

50

51 continue;

52 }

53 nbytes -= i;

54 cp += i;

55 lose_counter = 0;

56 }

57 }

58

59 for (i = 0; i < nbytes; i++)

60 {

61 if (seed == 0)

62 {

63 gettimeofday(&tv, 0);

64 seed = (getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec;

65 }

66 *cp++ = rand_r(&seed) & 0xFF;

67 }

68

69 return;

70 }

13行: 定義fd為靜態變數,這樣只打開一次設備。

17 – 19行: 無阻塞模式打開/dev/random設備。如果該設備打開失敗嘗試打開/dev/urandom。

29行: void get_random_bytes(void* buf, int nbytes)函數是提供給用戶的介面,用戶調用這個函數就可以得到隨機數。

37-57行: read有可能返回的位元組數小於請求的位元組數。這時候就循環讀直到讀夠了所請求的大小。這樣最多重復8次。然後返回。

59-67行: 如果上面重復8次都沒有讀夠所請求的位元組數,則我們自己生成隨機數來填充。

注意:打開的fd我們並沒有關閉,請您根據自己需求在合適的地方關閉。

3. Linux下的random()和srand(arg), rand()這兩個生成的隨機數有什麼區別。

首先我把這三個函數原型給你看一下
long random(void);
int rand(void);
void srand(unsigned seed);
random返回的是一個0到(2^31 - 1)的long類型整數
rand返回的是一個0到RAND_MAX的int類型整數

而你這里產生的隨機數序列是一樣的,這個很好解釋,因為你知道srand,但是你卻不知道還有一個srandom,這個函數是為random設置種子的,參數和srand一樣。
我的幫助手冊上甚至是這么寫的:
The random() and srandom() functions have (almost) the same calling sequence
and initialization properties as the rand(3) and srand(3) functions. The
difference is that rand(3) proces a much less random sequence -- in fact,
the low dozen bits generated by rand go through a cyclic pattern. All of
the bits generated by random() are usable. For example, `random()&01' will
proce a random binary value.

=============================
希望我的回答能給你帶來幫助

4. c語言用linux的ubuntu編程的時候b=rand()%3是把1到3的隨機數賦給b的意思嗎

是把 0,1,2中任意一個數賦值給b

閱讀全文

與linux下生成隨機數相關的資料

熱點內容
不用升級的角色游戲 瀏覽:919
大數據比對是什麼內容 瀏覽:617
華為分享照片存儲在哪個文件 瀏覽:296
windows7正在還原以前版本 瀏覽:738
醫學編程哪個好學 瀏覽:354
substancejar教程 瀏覽:760
網路游戲網站源碼 瀏覽:682
wordpress儀表盤登陸 瀏覽:454
ps文件很小是怎麼回事 瀏覽:124
蘋果文件丟失用什麼軟體找回便宜 瀏覽:148
大數據如何為政府服務 瀏覽:360
三星i9308怎麼升級 瀏覽:152
有哪些好的設計網站發布作品 瀏覽:964
miui7系統自帶app下載 瀏覽:61
做數據分析需要具備什麼 瀏覽:585
學通訊和編程哪個難 瀏覽:905
word背景保存 瀏覽:216
電腦里的文件怎麼判斷是否有用 瀏覽:324
小米4禁止後台程序 瀏覽:268
如何在word里添加excel圖表文件 瀏覽:280

友情鏈接