Java的java.util.Random可靠吗?

Is Java's java.util.Random reliable?

本问题已经有最佳答案,请猛点这里访问。

我忍不住注意到……在我开始开发我的数学游戏之后(在不断地修改之后,我把它交给了测试人员,但我还没有完成!)我使用java.util.Random及其方法nextInt()铸造成双倍可能不是我所寻找的可靠的救世主阶级。它是为像我这样的应用程序生成随机数吗?//这个应用程序的目的是制作一个对所有人都有挑战性的算术游戏,让你用整数和浮点参数来解决问题。我的程序生成的最高数字是一个6位数的数字,这是因为我对人类计算器(最高级别)的困难使用了不同的逻辑,也就是对于除法问题。我在考虑使用MelShan-Touter算法,但是我认为EDCOX1的0算法所使用的算法是这样的:http://DOCS.Oracle .COM/JavaSe/ 7 /DOCS/API/Java/UTL/NAPR.html,下一个%28 It% 29。

另外,我想知道是否建议我使用像new java.util.Random(System.currentTimeMillis())这样的东西


Random的no arg构造器已经基于当前时间(通过其cpu纳米时间而不是UTC日期),因此每次创建它都会得到不同的种子。种子Random(long)版本(在我的经验中)主要用于需要可预测输出的情况(例如,计算机游戏的一些程序生成例程允许玩家指定一个随机种子)

如果你非常担心你的随机数有多随机,你可能会想看看SecureRandom,它被推荐用于加密等的普通随机数。这里有一个关于如何使用它的很好的解释,也有一个关于这两者之间的区别的很好的解释。


其他的答案已经很好地涵盖了这一点,特别是Mfrankli关于统计随机和密码随机之间差异的答案。在你的情况下,你只需要后者,所以java.util.Random就足够了。

尽管如此,一个容易犯的错误(至少咬了我一次),就是在短时间内创建了许多Random实例。例如,每次需要随机数时都调用new Random()。您应该初始化一次Random,并尽可能地重新使用它。由于Random是从系统时间(甚至是在纳米尺度上)播种的,因此在非常接近的时间创建的一系列Random实例的输出将不会均匀分布。


简短回答:是的,对于您的应用,java.util.Random应该是可以的;简单地使用构造函数new java.util.Random()也应该是可以的,没有理由。

更长的答案:java.util.Random不是加密安全的——这里有一个技术定义,但本质上它不够"随机",安全人员无法安全地使用它;攻击者可能猜测产生的随机数字。但是,它还满足其他两个重要特性:

  • 类似于随机分布,即每个值都同样可能被生成。
  • 非确定性,即每次都会得到不同的值序列。
  • 换言之:你应该走得好。