我需要在random numbers
应用中生成C++
。我从阅读这两篇文章中得知 -
http://www.cprogramming.com/tutorial/random.html
- 可以使用srand()
和rand()
生成随机数,但在这两种情况下,根据system clock
的当前时间用作seed
。但我在第一篇文章中读到rand()
如果种子相同则会创建相同的随机数。因此,如果两个不同的用户同时运行我的应用程序,那么他们将具有相同的随机数。这将毫无意义,因为我需要随机数在大多数情况下是唯一的。 (我知道如果它们是随机生成的,它们真的是100%独特的)
所以我的问题是我可以创建一个不基于系统时间的随机种子,如果是这样,为什么rand()
使用相同的种子产生相同的数字,并且有一种方法可以使rand()
使用相同的种子生成不同的数字,还是有其他方法可以生成随机数?
答案 0 :(得分:7)
不使用特殊硬件(即便如此,这是有争议的),没有计算机生成的真正随机数。
有人说;你唯一的问题是:你如何生成种子,这样两个程序就不会生成相同的数字。使用当前时间作为种子的部分是合理的,但是正如您所理解的那样,这还不够,因为两个程序可以同时生成种子......所以你需要根据种子来增加种子这些程序之间的独特之处。可能性包括进程ID(如果两个程序在同一台计算机上会有所不同),硬件mac地址(如果两个程序都在不同的计算机上则会有所不同),或者用户执行某项任务需要多长时间(通常会只要用户是人,而不是自动化,就会有所不同。
答案 1 :(得分:3)
根据您的具体要求,您的解决方案可能很简单:
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;
}
答案 2 :(得分:1)
除了其他答案之外,在Linux(以及其他一些Unix)系统上,您可以从/dev/random或/dev/urandom
伪设备读取几个字节(至少为您的PNRG播种)。另请仔细阅读random(4)手册页(这也解释了/dev/random
与/dev/urandom
之间的重要区别)
如果编码最新的C++2011标准(而不是之前的标准),您可能会对其<random>
标头感兴趣。然后使用最新的GCC编译器(例如4.7)和libstdc++
库
答案 3 :(得分:0)
实现真正的随机数生成器是不可能的,但是有很多很好的伪随机函数实现可以帮助你:
<random>
标头文件:http://www.cplusplus.com/reference/std/random/ <stdlib.h>
函数的C rand()
头文件:http://www.cplusplus.com/reference/clibrary/cstdlib/rand/