【问题标题】:What is the difference between using std::random_device with pRNG e.g. std::mt19937 and without?将 std::random_device 与 pRNG 一起使用有什么区别,例如std::mt19937 和没有?
【发布时间】:2014-11-16 20:37:41
【问题描述】:

在 C++11 中,可以使用 std::random_device 生成数字,有或没有像 mt19937 这样的伪随机数生成器。

在这个示例代码中使用它会有什么不同:

#include <random>
#include <iostream>

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(1, 10);

    for (int i=0; i<16; ++i)
        std::cout << dist(rd) << "\t" << dist(mt) << "\n";
}

【问题讨论】:

标签: c++ c++11 random prng


【解决方案1】:

std::random_device 应该为您提供mt19937 等引擎的种子。产生的连续数字的质量是完全不确定的,并且对于实际目的(例如密码学)可能很容易不足,因此依赖它是没有问题的。

除此之外,mt19937 会在给定相同种子时给您相同的序列。 random_devices 的值只能受赋予其构造函数的字符串影响...这意味着实现定义的行为。

【讨论】:

    【解决方案2】:

    我知道有两个区别:

    1. 使用mt199937 会更快,但密码安全性较低。
    2. std::random_device 将始终是随机的,但如果您使用常量种子初始化您的 mt19937,它将始终为您提供相同的随机数:

      std::mt19937 mt(2014);

    每次都会给出相同的随机位序列。如果您想一遍又一遍地测试特定行为,这可能很有用。该标准在 26.5.5/4 中要求这样做:

    必需的行为:第 10000 次连续调用 mt19937 类型的默认构造对象应产生值 4123659995。

    std::random_device 没有这种等效的一致性。

    【讨论】:

    • @KarolyHorvath 是的,从技术上讲,仅用于默认构造,但这根本不是 random_device 的要求,这是我在 prng 中看到的唯一东西......
    • 并且只提到了一个值。诡异的。 (注意:你的意思是mt19937)。
    • 我的意思是 - 对 nth 的 random_device 值没有要求。然而,给定一个种子,mt19937 会给你一个特定的值序列。尽管这显然不在标准中。
    • 如果您对如何更好地表达我的答案有建议,我完全赞成 :)
    • @Barry,“std::random_device 将永远是随机的”是什么意思?是否保证使用外部随机源,如散热/鼠标点击/移动等? AFAIK,即使对于“std::random_device”,该标准也不保证“真正的”随机性。如果系统有真正rng的能力,它会使用它,否则没有,如果我错了,请纠正我。
    猜你喜欢
    • 2020-03-09
    • 2016-11-17
    • 2014-07-22
    • 2023-04-09
    • 2020-10-16
    • 2020-09-30
    • 2021-10-16
    • 2015-07-18
    • 2019-02-26
    相关资源
    最近更新 更多