我知道时间(0)通常用于播种随机数生成器,并且当程序每秒运行一次以上时它只会成为一个问题.我想知道在生成随机数时要考虑哪些更好的种子.我在Windows上阅读了有关GetTickCount,timeGetTime和QueryPerformanceCounter的内容.几乎所有的操作都能满足这些要求,还是有更好的播种选择?
这是一个使用boost库的快速代码示例:
#include <iostream>
#include <boost/random.hpp>
using namespace std;
using namespace boost;
int main()
{
mt19937 randGen(42);
uniform_int<> range(0,100);
variate_generator<mt19937&, uniform_int<> > GetRand(randGen, range);
for (int i = 0; i < 30; ++i)
cout << GetRand() << endl;
}
Run Code Online (Sandbox Code Playgroud)
Eri*_* J. 12
Netscape安全的一些早期攻击集中在知道何时发送加密数据包并缩小具有该知识的种子的可能范围.因此,获得蜱计数或其他甚至远程确定性的东西不是您最好的选择.
即使使用种子,"随机"数字的序列也是基于该种子的确定性的.内华达州博彩委员会的一名调查员意识到这一点,他应该检查某些位置并利用这些知识在被抓之前赚取相当多的钱.
如果您需要世界级的随机性,则可以向系统添加硬件,以提供高度随机化的数字.众所周知的扑克网站就是这样做的(至少,这就是他们所说的).
除此之外,结合您系统中的许多因素,这些因素都会以尽可能小的可预测性独立快速地变化,从而创造出非常好的种子.对SO的相关帖子的回答建议使用Guid.NewGuid().GetHashCode().由于Guid基于包括时间在内的许多确定性因素,因此不能成为种子的良好基础:
WinAPI GUID生成器的密码分析表明,由于V4 GUID的序列是伪随机的,给定初始状态,可以预测函数UuidCreate [2]返回的下一个250 000 GUID.这就是GUID不应该用于密码学的原因,例如,作为随机密钥.
来源:维基百科全球唯一标识符
在网上扑克的早期,关于32位种子的评论但有趣的故事太长了
ASF软件中使用的改组算法总是从一张有序的牌组开始,然后生成一系列用于重新排序牌组的随机数.在真正的卡片组中,有52个!(~2 ^ 226)可能独特的洗牌.回想一下,32位随机数发生器的种子必须是32位数,这意味着只有40多亿个可能的种子.由于甲板被重新初始化并且在每次洗牌之前发电机重新接通,因此该算法仅可能产生40亿次洗牌.4B可能的洗牌惊人地小于52!
RST开发的利用此漏洞的工具需要知道甲板上的五张卡.根据五张已知的牌,该节目搜索了几十万个可能的随机播放,并推断出哪一张是完美的匹配.在Texas Hold'em Poker的情况下,这意味着该程序将作弊玩家发出的两张牌加上前三张(翻牌圈)的前三张牌照作为输入.这四张牌在四轮投注中的第一轮之后就已知,并且足以确定(在比赛期间的实时)确切的随机播放.
http://www.ibm.com/developerworks/library/s-playing/
在unix系统上,您可以从/ dev/random中取几个字节作为RNG的种子./ dev/random应该是非常好的随机,使用PC上可用的不同熵源.当然,这完全取决于实现.
其中一个可能有用的情况是加密应用程序,因为时间(0)相对容易猜测.