最佳Java随机种子

时间:2011-12-20 07:38:20

标签: java random

关于将long提供给种子java.util.Random,如果我将对象实例化一次,似乎我只是把时间当作种子,这对于程序的生命是令人满意的,出于我的目的,意味着对nextDouble()的一系列调用的结果看起来是随机的。

假设代码简单的原因,我实例化Random,多次使用它,然后重新实例化,并重复。如果种子类似地提供,则种子将是相似的并且增加,因为它基于时间。如果它是自1970年1月1日以来的秒数,则增加量将小于该值。(编辑:此问题在2011年被提出。)

如果我链接nextDouble()的输出,那么使用非随机的基于时间的种子重新实例化Random会导致一个微妙的模式出现在{{1的输出的复合链中}}。另一种表达这个问题的方法是:我是否需要从nextDouble()的集合中统一绘制种子。

3 个答案:

答案 0 :(得分:7)

你可能会遇到这样的情况,确实会给他们分配相同的种子,特别是如果它们是在同一毫秒内创建的。有些机器的分辨率低至15毫秒或更高,因此它成为一个更大的问题。

解决此问题的一种方法是使用Math.random()。它使用一个系统范围的随机实例,它只在第一次使用时才被实例化。我不相信你有权访问底层实例,所以你不能用它来获取nextInt(),但你可以使用Math.random()获得双打,或者如果你真的想要自己的Random对象,那么来自double的{​​{1}},将其位转换为Math.random(),并使用long作为新long的种子。

可以找到随机的Oracle文档here

Random

答案 1 :(得分:4)

自动生成的随机种子使用System.nanoTime和计数器来确保它始终不同。恕我直言,没有必要使用种子来改善随机性

public Random() {
    this(seedUniquifier() ^ System.nanoTime());
}

private static long seedUniquifier() {
    // L'Ecuyer, "Tables of Linear Congruential Generators of
    // Different Sizes and Good Lattice Structure", 1999
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

Random使用48位种子并重复每2 ^ 48个调用,这意味着它无法生成每个可能的longdouble值。

与种子混淆听起来有点像三重随机策略,实际上并没有帮助。 http://thedailywtf.com/Articles/Random-Char-and-TriplyRandom-Double.aspx

如果您想要更大的随机性,请使用SecureRandom,即使您每次都给它1个种子,它也不会提供相同的随机序列。这可以产生每个可能的longdouble值。

答案 2 :(得分:2)

当然,这取决于生成器,但根据我的经验,对种子的微小更改会对生成的值产生很大影响。

可能通过一些工作可以检测到,但除非你正在进行高端统计工作或加密,否则它不会产生一些差别。

在任何情况下,如果 在该类型的域中,您将使用基于硬件的随机数生成,很可能使用类似3开尔文背景辐射的来源: - )< / p>