C 語言中生成隨機數

Jinku Hu 2023年1月30日 2021年1月22日
  1. 使用 randsrand 函式在 C 語言中生成隨機數
  2. 使用 randomsrandom 函式在 C 語言中生成隨機數
  3. 使用 getrandom 函式在 C 語言中生成隨機數
C 語言中生成隨機數

本文將介紹幾種如何在 C 語言中生成隨機數的方法。

使用 randsrand 函式在 C 語言中生成隨機數

rand 函式實現了一個偽隨機數生成器,可以提供一個範圍為 [0, RAND_MAX] 的整數,其中 RAND_MAX 在現代系統中是 231-1。注意,rand 函式背後的生成器演算法是確定性的。因此,它的種子位應該是隨機位。

srand 函式用於為偽隨機數生成器提供種子,隨後對 rand 的呼叫將產生隨機整數序列。在缺點方面,rand 的實現不希望產生均勻的隨機位。因此,rand 函式不建議在密碼學高度敏感的應用中使用。下面的例子用當前時間的值作為生成器的種子,這不是一個好的隨機性來源。

#include <stdio.h>
#include <string.h>
#include <stdlib.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

使用 randomsrandom 函式在 C 語言中生成隨機數

C 標準庫中可用的另一種偽隨機偽隨機數生成器是在 random 函式下實現的。與 rand 相比,這種方法是首選方法,但在敏感程式碼中,加密應用不應利用 random 函式。random 不接受任何引數,並返回 [0, RAND_MAX] 範圍內的 long int 型別的整數。該函式最好用 srandom 函式做種子,以產生質量相對較好的隨機數。

需要注意的是,和前面的例子一樣,我們使用 time 函式傳遞當前的時間值作為種子,在安全敏感的應用中不建議使用。

#include <stdio.h>
#include <string.h>
#include <stdlib.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 <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/random.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
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C Operator