我应该使用每次从标准:: random_device或使用std种子的随机引擎:: random_d

2019-06-26 18:43发布

我有一个包含随机性的两个来源的类。

std::random_device rd;
std::mt19937 random_engine;

我播种std::mt19937通过调用std::random_device 。 如果我要生成一个号码,我不关心重复性,我应该叫rd()random_engine()

在我的具体情况,我敢肯定,这两个会工作得很好,因为这会在一些网络代码在性能是不存在溢价被调用,结果并不特别敏感。 不过,我很感兴趣,一些关于何时使用硬件熵以及何时使用伪随机数“经验法则”。

目前,我只使用std::random_device种子我std::mt19937引擎,任何随机数生成我需要我的程序,我使用std::mt19937引擎。

编辑:下面是正是我使用这个特殊的例子什么的解释:

这是一个玩游戏的程序。 这个特定的游戏,用户可以开始前对对手一轮定制自己的“团队”。 建立一个战斗的一部分涉及派遣一组服务器。 我的程序有几支球队,并使用随机数来确定要装入的团队。 每一个新的战斗拨打电话时std::random_device种子伪随机数发生器。 我登录的战斗,其中包括这个团队,我随机选择和初始种子初始状态。

我问关于这个问题的特定的随机数是随机选择团队(其中,有利的是没有对手提前知道的时候,我使用的是什么球队,但不是关键任务),但我”可真要的是经验法则。 它是精细始终使用std::random_device如果我不需要我的号码的重复,或者是有使用起来比熵可以更快地采集的真正危险?

Answer 1:

该标准的做法,据我所知,是不是由计算机计算(但来自一些外部的,不可预知的源)一些种子随机数发生器。 这应该是你的RD()函数的情况。 从此,你可以调用每个伪随机数生成器(PRNG),而且你需要每一个伪随机数。

如果你担心不被这些数字足够随机的,那么你应该选择一个不同的PRNG。 熵是一种稀缺和宝贵的资源,应该受到同样的对待。 虽然,你可能不会需要很多的随机数,现在,你可能在未来; 或其他应用程序可能需要他们。 你想熵是随时可用的应用程序要求它。

这听起来像,为您的应用程序中,梅森倍捻机将满足您的需求就好了。 没有人谁扮演你的游戏永远不会觉得自己已加载的球队是不是随机的。



Answer 2:

如果你不使用它进行加密是很好,很好地重复使用由种子mt19937 random_engine

对于这个答案的其余部分,我假设你使用的是随机数在您的网络代码加密。 总之,mt19937不适合使用。

http://en.wikipedia.org/wiki/Mersenne_twister#Disadvantages

还有就是你会泄漏信息(可能是间接的),随着时间的推移,这样攻击者就可以开始预测的随机数的潜在风险。 至少在理论上,但这就是它的约。 维基百科

......因为这个数字是状态向量的从大小
其未来迭代产生)允许预测所有未来迭代。

防止随机数生成信息泄漏给用户的一个简单的方法是使用单向散列函数,但还有更给它。 您应该使用专为目的的随机数生成器:

http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator

各种实例(有代码)是在这里找到http://xlinux.nist.gov/dads/HTML/pseudorandomNumberGen.html



Answer 3:

如果您需要随机性模拟或游戏,那么你做的很好。 调用随机器只有一次,并做一切与随机种子伪RNG。 作为奖励,你应该存储在日志文件中的种子值,以便可以在以后重播伪随机序列:

auto const seed = std::random_device()();
// save "seed" to log file
std::mt19937 random_engine(seed);

(对于多线程,使用PRNG在主线程以产生用于在产生的线程进一步的PRNG种子。)

如果你需要很多真正的随机性的用于加密目的,那么PRNG从来都不是一个好主意,不过,因为输出的长序列包含比真正的随机性随意性少了很多,即您可以从一小部分预测它的全部。 如果你需要真正的随机性,你应该从一些不可预知的来源(例如热传感器,用户键盘/鼠标活动,等等)收集。 Unix的/dev/random可能是这样的“真正的随机性”源,但它可能不会很快填满。



Answer 4:

你可能想看看http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful这可以解释为什么你应该使用uniform_int_distribution和random_device / mt19937的亲属优势。

在此视频,斯蒂芬T. Lavavej特别指出视觉C ++,random_device可用于加密目的。



Answer 5:

答案是依赖于平台。 我似乎记得使用Visual C ++ 2010,的std :: random_device只是mt19937在一些无证的方式播种。

当然,你知道,基于随机数发生器的任何特设加密方案很可能是非常弱的。



Answer 6:

假设这不是加密的目的,要记住的随机数生成的最重要的事情是考虑你想要怎样的随机数的分布是,什么是你期望的范围内。

通常库中的标准随机数生成器的目的是给予了均匀分布。 因此,数字将0和一些RAND_MAX之间的范围内(32位计算机上说,这是2 ^ 31 -1)

现在,这里是伪随机数生成器要记住的东西。 他们中的大多数被设计来产生随机数,而不是随机位。 所不同的是微妙的。 如果你需要0-8大多数程序员之间的数字会说兰特()%8这是不好的,因为该算法是对随机32位。 但是,你正在使用只有底部3位。 不好。 这不会给你一个均匀分布(假设这是你在找什么)

您应该使用8 *(RAND()+ 1)/(RAND_MAX)现在给你0和8之间的均匀随机数。

现在,随着硬件随机数生成器,你可能有正在生产随机位。 如果确实如此,那么你有独立生成每个位。 然后它更像一组相同的独立的随机比特。 这里的造型必须是一个有点不同。 记住这一点,尤其是在模拟的分布变得重要。



文章来源: Should I use a random engine seeded from std::random_device or use std::random_device every time
标签: c++ random c++11