生成真正的随机数

Generating Truly Random Numbers

本文关键字:随机数      更新时间:2023-10-16

可能的重复:
有效地生成随机数

我需要在C++应用程序中生成random numbers。我看了这两篇文章就知道了——

http://www.cprogramming.com/tutorial/random.html

编写一个 C 函数,该函数在给定特定范围的情况下生成一个随机数、一对随机数或三元组随机数

-- 可以使用srand()rand()生成随机数,但在这两种情况下,根据system clock的当前时间都用作seed。但我在第一篇文章中读到,如果种子相同,rand()将创建相同的随机数。因此,如果两个不同的用户同时运行我的应用程序,那么他们将具有相同的随机数。这将是没有意义的,因为我需要随机数在大多数情况下是唯一的。 (我知道如果它们是随机生成的,它们不可能真正 100% 唯一)

所以我的问题是我可以创建一个不基于系统时间的随机种子吗?如果是这样,为什么rand()使用相同的种子产生相同的数字,有没有办法让rand()产生不同的数字使用相同的种子,或者有没有其他方法生成随机数?

如果不使用特殊的硬件(即使这样,这也是有争议的),就没有计算机生成的真正随机数这样的东西。

话虽如此;你唯一的问题是:你如何生成你的种子,使两个程序不会产生相同的数字。使用当前时间作为种子的一部分是合理的,但如您所知,这还不够,因为两个程序可以同时生成它们的种子......因此,您需要根据程序之间独特的内容来增加种子。可能性包括进程 ID(如果两个程序在同一台计算机上,则不同)、硬件 mac 地址(如果两个程序位于不同的计算机上,则不同)或用户执行某些任务所需的时间(只要用户是人类,而不是自动化,通常会有所不同)。

根据您的确切要求,您的解决方案可能很简单:

struct timeval;
gettimeofday(&time, NULL);
srand(hash3(time.tv_sec, time.tv_usec, getpid()));

您可以使用任意三个整数哈希函数,例如:

unsigned int hash3(unsigned int h1, unsigned int h2, unsigned int h3)
{
return ((h1 * 2654435789U) + h2) * 2654435789U) + h3;
}

除了其他答案之外,在Linux(和其他一些Unix)系统上,您可以从/dev/random或/dev/urandom伪设备读取几个字节(至少可以播种PNRG)。还要仔细阅读 random(4) 手册页(这也解释了/dev/random/dev/urandom之间的重要区别)

如果编码最新的 C++2011 标准(而不是以前的标准),您可能会对其<random>标头感兴趣。然后使用最新的 GCC 编译器(例如 4.7)和libstdc++

实现真正的随机数生成器是不可能的,但有许多不错的伪随机函数实现可能会帮助您:

  1. 提升随机: http://www.boost.org/doc/libs/1_51_0/doc/html/boost_random.html
  2. C++11<random>头文件:http://www.cplusplus.com/reference/std/random/
  3. 包含rand()函数的 C<stdlib.h>头文件:http://www.cplusplus.com/reference/clibrary/cstdlib/rand/