【问题标题】:How does java Random() find a seed?java Random() 如何找到种子?
【发布时间】:2020-11-05 05:57:52
【问题描述】:

根据我的研究,每个人似乎都说 java random 在未指定时使用系统时间(以毫秒为单位)作为其默认种子。因此,如果我们在生成随机数的那一刻有系统时间,那么我们应该能够知道生成该数字的种子是什么。 所以,

(new Random()).nextLong;
long time = System.currentTimeMillis();
(new Random(time)).nextLong

应该产生两个相同的数字,因为种子是相同的,对吧?它没有使用 TimeMillis 作为种子,或者我做错了其他事情。

非常感谢您的帮助,我已经搜索了几个小时,但似乎找不到一致的答案。我只想知道当没有指定种子时它是如何找到种子的。我的想法可能是它确实使用了系统时间,但在最终种子之前它会乘以它等。

再次感谢:)

【问题讨论】:

  • 我想说,由于随机函数需要时间,System.currentTimeMillis() 与用于第一个随机种子时的不同。
  • 无论如何人们似乎都没有意识到the source code for the standard library is readily available 并且大多非常容易阅读。
  • 我检查了前后的时间,两者的时间相同,所以应该不是那个
  • Federico 我在哪里可以找到它?我找了一会儿,不知怎么只找到了一个旧版本,谢谢

标签: java random random-seed


【解决方案1】:

Java 过去使用系统时间作为默认种子,直到 1.4.2。在 1.5 中,这个“错误”得到了修复。比较1.4.2 API specification

创建一个新的随机数生成器。它的种子根据当前时间初始化为一个值:

public Random() { this(System.currentTimeMillis()); }

在同一毫秒内创建的两个 Random 对象将具有相同的随机数序列。

1.5 API specification

创建一个新的随机数生成器。此构造函数将随机数生成器的种子设置为一个很可能与此构造函数的任何其他调用不同的值。

OpenJDK 中的当前实现使用静态AtomicLong,每次您创建一个没有种子的新Random 实例时都会更新它。如果本地没有源代码,可以在source code on github找到:

    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 * 1181783497276652981L;
            if (seedUniquifier.compareAndSet(current, next))
                return next;
        }
    }

    private static final AtomicLong seedUniquifier
        = new AtomicLong(8682522807148012L);

【讨论】:

  • 对于未来感兴趣的读者:Python 使用Mersenne Twister 作为核心生成器。 Here 是两者之间的有趣比较。
  • 啊,好的,谢谢,所以没有办法从输出和时间中找到种子吗?我之所以问,是因为我正在审查其他人的代码,他们似乎正在尝试利用时间来验证种子是否正确生成。我猜从时间和随机输出来看,有可能找到原子长吗?感谢您为我解决这个问题
  • 您可能完全可以从 Random 方法调用结果中找到种子,但我认为这并不容易。您可以使用反射 API 直接读取 Random 对象的内部结构。
  • @parad0x5983 通过询问听起来您需要加密 RNG,java.util.Random 不是。你可以改用SecureRandom
猜你喜欢
  • 2011-08-25
  • 2016-04-02
  • 1970-01-01
  • 2017-08-05
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-07
相关资源
最近更新 更多