Java的java.util.Random可靠吗?

时间:2013-06-24 04:28:37

标签: java random mersenne-twister

我不禁注意到......在我开始开发我的数学游戏之后(经过不断的调整后将它交给beta测试者,我还没有完成!)我使用了java.util.Random和它的方法nextInt()铸造成双倍可能不是我正在寻找的可靠的救世主类。它是否为像我这样的应用程序生成随机数? //这个应用程序的目的是制作一个对ALL PEOPLE具有挑战性的算术游戏,让你解决整数和浮点参数的问题。我的程序生成的最高数字是一个6位数字,这是因为我用于人类计算器(最高级别)难度的一些不同逻辑,即分裂问题。我在考虑使用Mersenne twister算法,但我认为java.util.Random使用的算法是这样的:http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#next%28int%29

此外,我想知道是否建议使用new java.util.Random(System.currentTimeMillis())

之类的内容

3 个答案:

答案 0 :(得分:6)

Random的无参数构造函数已经基于当前时间(通过其cpu nanoTime而不是UTC日期),所以只需创建它就会每次都获得不同的种子。种子Random(long)版本(根据我的经验)主要用于需要可预测的输出(例如,计算机游戏的某些程序生成例程,允许玩家指定随机种子)

如果您非常担心随机数是多么随机,您可能需要查看SecureRandom,建议使用普通随机数进行加密等。有一个很好的解释如何使用它here和非常好的解释两个here之间的区别

答案 1 :(得分:3)

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

所有这一切,一个容易犯的错误(至少咬过我一次),是在很短的时间内创建了许多Random个实例。例如,每次需要随机数时调用new Random()。您应该初始化Random一次并尽可能地重复使用它。由于Random是在系统时间之外播种的(即使是纳米级别),因此在非常接近同一时间创建的一系列Random实例的输出将不会均匀分布。

答案 2 :(得分:2)

简短回答:是的,java.util.Random对您的申请应该没问题;并且只使用构造函数new java.util.Random(),没有参数,也应该没问题。

更长的答案:java.util.Random 加密安全 - 这里有一个技术定义,但基本上它并非“随机”,以便安全人员感到安全使用它;攻击者可能会猜测产生的随机数。但是,它满足了另外两个重要属性:

  1. 类似于随机分布,即每个值同样可能生成。
  2. 非确定性,即每次都会得到不同的值序列。
  3. 换句话说:你应该好好去。