【问题标题】:Is Java's java.util.Random reliable? [duplicate]Java 的 java.util.Random 可靠吗? [复制]
【发布时间】:2013-06-20 12:29:16
【问题描述】:

我不禁注意到...在我开始开发我的数学游戏后(并在不断调整它后将其提供给 beta 测试人员,但我仍然没有完成!)我使用 java.util.Random 及其方法nextInt() 转换为 double 可能不是我正在寻找的可靠的救世主类。是为像我这样的应用程序生成随机数吗? //这个应用程序的重点是制作一个对所有人都具有挑战性的算术游戏,让您解决整数和浮点参数的问题。我的程序生成的最高数字是 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())之类的东西

【问题讨论】:

  • ....定义“可靠”?
  • 你也可以使用java.util.UUID
  • 我认为您不应该使用new java.util.Random(System.currentTimeMillis()),因为种子将被限制为毫秒(甚至更大)的分辨率。

标签: java random mersenne-twister


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 你的建议正是我所做的!
    • +1 用于指出 “一个简单的错误” ..这是我个人犯的,并从那时起纠正了 100 多次。
    【解决方案3】:

    简短回答:是的,java.util.Random 应该适合您的应用程序;并且简单地使用构造函数new java.util.Random(),不带参数也应该没问题。

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

    1. 类似于随机分布,即每个值产生的可能性相同。
    2. 非确定性,即每次都会得到不同的值序列。

    换句话说:你应该很高兴。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2012-03-05
      • 2013-01-18
      相关资源
      最近更新 更多