C++ 生成真正的随机数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12662810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:29:46  来源:igfitidea点击:

Generating Truly Random Numbers

c++randomunique

提问by John Vulconshinz

Possible Duplicate:
Generating random numbers effectively

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

I need to generate random numbersin my C++application. I know from reading these two articles --

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

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

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

write a c function that generates one random number, or a pair of random numbers, or a triplet of random numbers given the particular ranges

编写 ac 函数,生成一个随机数,或一对随机数,或给定特定范围的随机数三元组

-- that random numbers can be generated using srand()and rand()but in both cases the current time according to the system clockis used as a seed. But I read in the first article that rand()will create the same random numbers if the seed is the same. So if two different users ran my application at the same time then they would have the same random numbers. Which would be pointless because I need the random numbers to be unique for the most part. (I know they cant be truly 100% unique if they are generated randomly)

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

So my question is can I create a random seed not based on system time and if so how, why does rand()produce the same numbers with the same seed and is there a way to make rand()produce different numbers with the same seed, or is there any other way to generate random numbers?

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

回答by mah

Without using special hardware (and even then, it's debatable), there is no such thing as a truly random number generated by a computer.

如果不使用特殊硬件(即便如此,这也是有争议的),计算机生成的真正随机数是不存在的。

That being said; your only problem is: how do you generate your seeds such that two programs will not generate the same number. Using the current time as partof your seed is reasonable, but as you understand, it's not enough because two programs could generate their seed at the same time... so you need to augment your seed based on something that will be unique between the programs. Possibilities include process ID (which will differ if both programs are on the same computer), hardware mac address (which will differ if both programs are on different computers), or timing how long it takes the user to perform some task (which will generally differ as long as the user is human, not automation).

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

回答by David Schwartz

Depending on your exact requirements, your solution might be as simple this:

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

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

You can use any three integer hashing function, such as this one:

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

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

回答by Basile Starynkevitch

In addition of other answers, on Linux (and some other Unix) systems, you could read a few bytes from the /dev/randomor /dev/urandompseudo-device (at least to seed your PNRG). Read also carefully the random(4)man page (which also explains the important difference between /dev/randomand /dev/urandom)

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

If coding for the latest C++2011standard (and not the previous ones), you could be interested by its <random>header. Then use a very recent GCCcompiler (e.g. 4.7) and libstdc++library

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

回答by Rontogiannis Aristofanis

It's not possible to implement a truly random number generator, but there are many nice pseudo-random function implementations that might help you:

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

  1. Boost.Random: http://www.boost.org/doc/libs/1_51_0/doc/html/boost_random.html
  2. The C++11 <random>header file: http://www.cplusplus.com/reference/std/random/
  3. The C <stdlib.h>header file which includes the rand()function: http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
  1. Boost.Random: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. <stdlib.h>包含rand()函数的 C头文件:http: //www.cplusplus.com/reference/clibrary/cstdlib/rand/