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