C 語言中生成隨機數
本文將介紹幾種如何在 C 語言中生成隨機數的方法。
使用 rand
和 srand
函式在 C 語言中生成隨機數
rand
函式實現了一個偽隨機數生成器,可以提供一個範圍為 [0, RAND_MAX]
的整數,其中 RAND_MAX
在現代系統中是 231-1。注意,rand
函式背後的生成器演算法是確定性的。因此,它的種子位應該是隨機位。
srand
函式用於為偽隨機數生成器提供種子,隨後對 rand
的呼叫將產生隨機整數序列。在缺點方面,rand
的實現不希望產生均勻的隨機位。因此,rand
函式不建議在密碼學高度敏感的應用中使用。下面的例子用當前時間的值作為生成器的種子,這不是一個好的隨機性來源。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
srand(time(NULL));
for (int i = 0; i < NUMS_TO_GENERATE; i++) {
printf("%d\n", rand() % MAX);
}
exit(EXIT_SUCCESS);
}
輸出:
85084
91989
85251
85016
43001
54883
8122
84491
6195
54793
使用 random
和 srandom
函式在 C 語言中生成隨機數
C 標準庫中可用的另一種偽隨機偽隨機數生成器是在 random
函式下實現的。與 rand
相比,這種方法是首選方法,但在敏感程式碼中,加密應用不應利用 random
函式。random
不接受任何引數,並返回 [0, RAND_MAX]
範圍內的 long int
型別的整數。該函式最好用 srandom
函式做種子,以產生質量相對較好的隨機數。
需要注意的是,和前面的例子一樣,我們使用 time
函式傳遞當前的時間值作為種子,在安全敏感的應用中不建議使用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/random.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
srandom(time(NULL));
for (int i = 0; i < NUMS_TO_GENERATE; i++) {
printf("%ld\n", random() / MAX);
}
printf("\n");
exit(EXIT_SUCCESS);
}
輸出:
91
2019
2410
11784
9139
5858
5293
17558
16625
3069
使用 getrandom
函式在 C 語言中生成隨機數
getrandom
是一個 Linux 特有的函式,用於獲取隨機位元,其質量遠遠高於之前提供的兩種方法。getrandom
需要三個引數-void
指標,指向應該儲存隨機位元的緩衝區,緩衝區的位元組大小,以及特殊功能的標誌。
在下面的例子中,我們生成一個無符號的整數,其中&tmp
的地址被傳遞為儲存隨機位的緩衝區,大小用 sizeof
運算子計算。在極少數情況下,getrandom
檢索位的隨機性來源可以不初始化。對 getrandom
函式的呼叫將阻止程式的執行。因此,GRND_NONBLOCK
巨集定義作為第三個引數傳遞給函式,以便在這些情況下立即返回錯誤值 -1
。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/random.h>
#include <time.h>
#define MAX 100000
#define SIZE 100
#define NUMS_TO_GENERATE 10
int main() {
unsigned int tmp;
getrandom(&tmp, sizeof(unsigned int), GRND_NONBLOCK) == -1
? perror("getrandom")
: "";
printf("%u\n", tmp);
exit(EXIT_SUCCESS);
}
934103271