不同语言(即Java和C ++)中的“随机”生成器如何比较?

尽管标题很奇怪,我想问一个合理的问题:哪个方法生成的数字更随机 :Java的Random()类或Math.random() ,或C ++的rand()

我听说PHP的rand()非常糟糕,即如果你映射它的结果你可以清楚地看到一个模式; 遗憾的是,我不知道如何用C ++或Java绘制地图。

另外,只是出于兴趣,C#怎么样?

Java和C ++都生成伪随机数,它们是:

  • 适合任何不是统计学家或密码学家的人(a) ; 要么
  • 对于这两类人来说,这是不合适的。

老实说,除非你在其中一个类中,否则伪随机数生成器就可以了。

Java也有SecureRandom ,它声称提供加密类非确定性(我不能评论该论点的真实性),C ++现在拥有比rand()更多种类的随机数生成能力 – 参见详情。

特定操作系统可以为随机数生成器提供熵源,例如Windows下的CryptGenRandom或Linux下的/dev/random 。 或者,您可以使用随机事件(例如用户输入时序)添加熵。


(a)实际上可能包含非统计学家或密码学家的其他工作类型的痕迹:-)

java.util.Random (由Math.random()内部使用)使用线性同余生成器 ,这是一个相当弱的RNG,但足以用于简单的事情。 对于重要的应用程序,应该使用java.security.SecureRandom

我不认为C或C ++语言规范禁止用于rand()的算法,但大多数实现也使用LCG。 C ++ 11添加了新的API,可以产生更高质量的随机性。

有一个非常好的文档可以在网上找到,由一位全球随机数发生器专家完成。

这是文件

本文档的第一部分是对测试的描述,除非您真正感兴趣,否则您可以跳过这些测试。 从第27页开始,有许多生成器的不同测试结果,包括Java,C ++,Matlab,Mathematica,Excel,Boost,……(它们在文中描述)。

似乎Java的生成器有点好,但两者都不是世界上最好的。 C ++ 11的MT19937已经好多了。

PHP使用种子。 如果种子在两个不同的时间是相同的,则rand()函数将始终输出相同的内容。 (例如,对于令牌来说这可能非常糟糕)。 我不知道C ++和Java,但是没有真正的随机性,这使得质量难以评估。 安全不依赖于这些function。

我不知道随机数是真正随机的任何语言 – 我确信这样的事情存在,但一般来说,它是“你坚持种子,你得到种子给出的序列”。 如果你想做一个简单的’shootem-up’游戏,基本的扑克游戏,家庭使用的轮盘模拟器等等,这很好。但如果你有钱依赖游戏是真正随机的(例如,你给钱根据某些序列的结果)或您的秘密文件依赖于您的随机数,那么您肯定需要一些其他机制来查找随机数。

并且有一些“真正的”随机数发生器。 它们不提供种子,因此基于您上次获得的数量的可预测性很低。 我不是说它是零,因为我不确定你是否可以通过在未使用的射频,放射性衰变或任何最新的真随机数的方法中采样无线电波来获得它。