導航:首頁 > 編程系統 > 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下生成隨機數相關的資料

熱點內容
怎麼樣讓自己的網站不被別人看到 瀏覽:711
編程擴展效果如何 瀏覽:335
榮耀暢玩手環同步qq 瀏覽:475
怎麼向sql中添加資料庫 瀏覽:596
錄歌失敗重啟app什麼意思 瀏覽:522
壓縮文件包怎麼在微信發送 瀏覽:432
mysql資料庫怎麼插入時間值 瀏覽:191
微信視頻不能轉發朋友圈 瀏覽:596
影視後期的app有哪些 瀏覽:956
電子保單數據出錯什麼意思 瀏覽:368
如何以文件下載音樂 瀏覽:438
計算機網路章節練習 瀏覽:999
單片機的外部中斷程序 瀏覽:48
表格批量更名找不到指定文件 瀏覽:869
js的elseif 瀏覽:584
3dmaxvray視頻教程 瀏覽:905
imgtool工具中文版 瀏覽:539
java幫助文件在哪裡 瀏覽:965
win10切換輸入語言 瀏覽:696
haier電視網路用不了怎麼辦 瀏覽:361

友情鏈接