有没有一个函数生成一个随机int数在C?或者我必须使用第三方库?


当前回答

试试这个,我把上面已经提到的一些概念放在一起:

/*    
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
 */

int random(int max) {
    srand((unsigned) time(NULL));
    return (rand() % max) + 1;
}

其他回答

试试这个,我把上面已经提到的一些概念放在一起:

/*    
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
 */

int random(int max) {
    srand((unsigned) time(NULL));
    return (rand() % max) + 1;
}

在现代的x86_64 cpu上,您可以通过_rdrand64_step()使用硬件随机数生成器。

示例代码:

#include <immintrin.h>

uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
  // Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number

如果您需要128个安全随机位,符合RFC 1750的解决方案是读取已知可以生成可用熵位的硬件源(例如旋转磁盘)。更好的是,好的实现应该使用混合函数组合多个源,并最终通过重新映射或删除输出来消除输出分布的倾斜。

如果你需要更多的比特,你需要做的就是从128个安全随机比特的序列开始,并将其拉伸到所需的长度,将其映射到人类可读的文本等等。

如果你想在C中生成一个安全的随机数,我将遵循这里的源代码:

https://wiki.sei.cmu.edu/confluence/display/c/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers

注意,对于Windows bbcryptgenrandom是使用的,而不是CryptGenRandom,在过去的20年里已经变得不安全。您可以亲自确认BCryptGenRandom符合RFC 1750。

For POSIX-compliant operating systems, e.g. Ubuntu (a flavor of Linux), you can simply read from /dev/urandom or /dev/random, which is a file-like interface to a device that generates bits of entropy by combining multiple sources in an RFC 1750 compliant fashion. You can read a desired number of bytes from these "files" with read or fread just like you would any other file, but note that reads from /dev/random will block until a enough new bits of entropy are available, whereas /dev/urandom will not, which can be a security issue. You can get around that by checking the size of the available entropy pool, either my reading from entropy_avail, or by using ioctl.

我们来看看这个。首先,我们使用srand()函数来为随机化器播种。基本上,计算机可以根据输入给srand()的数字生成随机数。如果你给出相同的种子值,那么每次都会生成相同的随机数。

因此,我们必须用一个总是在变化的值来给随机化器播种。我们通过time()函数将当前时间的值提供给它来实现这一点。

现在,当我们调用rand()时,每次都会产生一个新的随机数。

    #include <stdio.h>

    int random_number(int min_num, int max_num);

    int main(void)
    {
        printf("Min : 1 Max : 40 %d\n", random_number(1,40));
        printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));
        return 0;
    }

    int random_number(int min_num, int max_num)
    {
        int result = 0, low_num = 0, hi_num = 0;

        if (min_num < max_num)
        {
            low_num = min_num;
            hi_num = max_num + 1; // include max_num in output
        } else {
            low_num = max_num + 1; // include max_num in output
            hi_num = min_num;
        }

        srand(time(NULL));
        result = (rand() % (hi_num - low_num)) + low_num;
        return result;
    }

在我最近的应用程序中,我遇到了一个严重的伪随机数生成器问题:我多次通过Python脚本调用我的C程序,并使用以下代码作为种子:

srand(time(NULL))

然而,由于:

Rand将生成相同的伪随机序列,在srand中给出相同的种子(参见man srand); 如前所述,time函数每秒只会变化:如果应用程序在同一秒内运行多次,time每次都会返回相同的值。

我的程序生成了相同的数字序列。 你可以做三件事来解决这个问题:

mix time output with some other information changing on runs (in my application, the output name): srand(time(NULL) | getHashOfString(outputName)) I used djb2 as my hash function. Increase time resolution. On my platform, clock_gettime was available, so I use it: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec); Use both methods together: #include<time.h> struct timespec nanos; clock_gettime(CLOCK_MONOTONIC, &nanos) srand(nanos.tv_nsec | getHashOfString(outputName));

选项3确保了你(据我所知)最好的种子随机性,但它可能只会在非常快速的应用中产生差异。 在我看来,选择2是一个安全的赌注。