【问题标题】:Generating Truly Random Numbers [duplicate]生成真正的随机数
【发布时间】:2012-09-30 16:17:24
【问题描述】:

可能重复:
Generating random numbers effectively

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

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

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

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

【问题讨论】:

  • 不清楚你的需求是什么,你的平台是什么。例如,在大多数 x86 平台上,您可以获得十亿分之一秒的时间测量(来自 TSC),这使得两个用户同时运行您的程序的机会实际上为零。 (您的问题的确切答案在很大程度上取决于您的确切要求和您的平台。)
  • 如果没有外部噪声源,您无法生成真正的随机数 - 您能做的最好的就是伪随机数。
  • Kolmogorov complexity 不可计算。
  • 您始终可以在<random> 标头中使用更好的选项之一。
  • @DavidSchwartz 函数 time() 是精确的还是我需要使用其他东西?为了回答你的问题,我正在 x86(Linux) 上编写应用程序。

标签: c++ random unique


【解决方案1】:

如果不使用特殊硬件(即使那样,也值得商榷),就不会有计算机生成真正的随机数。

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

【讨论】:

  • 进程 ID(在 Windows/Linux 上)是从公式还是其他东西生成的?感谢您的快速回复。
  • 进程 ID 在大多数系统上的创建是相当线性的(尽管这取决于系统,并且由于冲突/重用,最终它们的直接线性是不可能的)。但是,如果您按照@David Schwartz 的建议将 pid 用作哈希的一部分,即使它们靠近,也会导致您的种子从一个 pid 到下一个 pid 显着变化。
【解决方案2】:

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

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;
}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      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. 包含rand()函数的C <stdlib.h>头文件:http://www.cplusplus.com/reference/clibrary/cstdlib/rand/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-09
        • 2013-10-06
        • 2017-08-15
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多