【问题标题】:C - Random 0 to INT_MAX on linuxC - Linux上的随机0到INT_MAX
【发布时间】:2014-12-01 07:33:36
【问题描述】:

在 linux 上是否有相当于 windows rand_s 的功能? 确实,rand 函数,但生成 0 和 UINT_MAX 之间的随机数` (4294967295)

我有组合一些数字 rand() 来创建一个大兰特的解决方案,但我很确定概率将不再是 1/UINT_MAX(因为 rand 是一个伪随机函数,我在这里计算一系列rand 调用)。 例如,下面会生成 0 到 4000000000 之间的数字:

unsigned int random = (unsigned int)((unsigned int)((rand()%4) * 1000000000) + (rand()%10) * 100000000 + (rand()%10) * 10000000 + (rand()%10) * 1000000 + (rand()%10) * 100000 + (rand()%10) * 10000 + (rand()%10) * 1000 + (rand()%10) * 100 + (rand()%10) * 10 + rand()%10);

提前致谢。


这是一段有效的代码(非常感谢 Dan)

#include <stdio.h>
#include <stdlib.h>

#include <fcntl.h>
#include <unistd.h>

int main()
{
    int i, randomSrc = open("/dev/urandom", O_RDONLY);
    unsigned int random;

    for(i=0;i<1000;i++)
    {
            read(randomSrc , &random, sizeof(unsigned int));
            printf("%u\n",random);
    }

    close(randomSrc);

    return 0;
}

【问题讨论】:

  • INT_MAX 在 32 位平台上为 2147483647。你是这个意思,还是UINT_MAX (4294967295)?除非您使用 long,否则您将无法达到 4294967296。
  • 你说得对,对不起,我有点累了。 (但实际上,介于 0 和 INT_MAX 之间的随机数会非常好;))
  • 您生成大范围随机数的方法似乎浪费了熵和时钟周期。如果(U)INT_MAX 小于您想要的范围,为什么不将2 个调用的输出连接到rand()。我认为,您认为高位随机性较小的假设(不再)是不正确的。
  • @Will AFAIK LCG 的低位随机性较低。

标签: c linux random int


【解决方案1】:

您可以使用来自 stdlib.h 的相同伪随机数生成器,但 Linux 还提供了一个位于 /dev/urandom 的实数随机数生成器,它是一个加密安全的随机数生成器,它收集称为熵位的随机位。这是一篇 SO 文章。

How to use /dev/random or urandom in C?

【讨论】:

  • 这正是我正在寻找的,非常感谢!
【解决方案2】:

大多数标准库实现中的rand() 函数是一个劣质的伪随机数生成器。反复调用它的缺点更加突出。

由于您声明您使用的是 Linux,因此您可以从系统设备而不是库函数访问更好的伪随机数生成器。例如:

FILE fd_urandom = fopen("/dev/urandom", "r");

。 . .

int urand;
size_t count = fread(&urand, sizeof(int), 1, fd_urandom);
if (count < 1) {
  /* handle error */
}

。 . .

fclose(fd_urandom);

sizeof(int) 必须与urand 的大小匹配,所以如果将urand 更改为long,则还需要更改为sizeof(long)。

我不确定fread(address、size、count、fd_urandom) 的速度有多快,但如果你想要一堆伪随机数,你最好在一个时间并将它们保存在缓冲区中。

/dev/urandom 是一个非常高质量的伪随机数生成器,适用于大多数用途。还有一个/dev/random,仅用于某些安全应用(如加密密钥);它的缺点是如果它认为它不能提供足够“随机”的数字,它可能会阻塞。

【讨论】:

  • 注意我注意到 urandom 会导致严重的延迟,对于大量数字来说它不是很快。如果是这种情况,最好从 urandom 读取一个数字并将其用作随机生成器的良好库实现的种子。
  • @Vality 我怀疑/dev/urandom 可能有点慢。我没有尝试分析它,但我已经阅读了代码,它看起来计算成本很高。使用它来播种一个好的库伪随机数生成器是加速代码的好方法,但生成器应该比通常的库rand() 更好。这个问题提到了改进的 Mersenne Twister:stackoverflow.com/questions/4720822/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多