gpt4 book ai didi

java - 具有跨不同 Java 版本的恒定种子的 Random 的可靠性

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:39:51 25 4
gpt4 key购买 nike

在我们的应用程序中,我们使用 Random 和 SecureRandom 为某些客户生成一些非常大的信息集。经过一些测量,我们意识到使用存储在磁盘上的种子重新生成信息比存储和读取该信息更快,占用的内存更少。我查看了 javadoc,但没有看到任何保证给定 常量 种子 n 的结果,比方说,new Random(n).nextInt() 在不同的 Java 版本中应该是相同的。

我的问题是:对于 Java 8 和以前的版本,这是一个安全的假设吗,Java 8 中的 new Random(n).nextInt() 应该返回与以前版本的 Java 中的值相同吗?

(为了公平起见,我会接受回答上述问题的答案,即使他们不回答下面的问题。)

虽然我知道不能保证以后的 Java 版本也是如此,并且第二个问题将征求一些意见,但您认为 future 的 Java 版本改变用于生成的算法的可能性有多大使用 Random 和 SecureRandom 的伪随机数?

谢谢!

最佳答案

是的,这在 Java 8 的所有版本中都保证了 Random。不过,SecureRandom 似乎没有任何类似的保证。

如果您查看 Javadocs for Random ,你可以看到这个:

If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers. In order to guarantee this property, particular algorithms are specified for the class Random. Java implementations must use all the algorithms shown here for the class Random, for the sake of absolute portability of Java code. However, subclasses of class Random are permitted to use other algorithms, so long as they adhere to the general contracts for all the methods.

强调我的。因此,显然对这个问题进行了一些思考,并决定在该类的文档中指定底层算法。理论上,人们可以提供不同的实现,但这样就不符合 Java 规范。

要获得更多证据,请查看版本之间的实现情况。例如,next 方法在每个版本中的定义方式都完全相同,至少从 Java 1.4 开始(据我所知)。

seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));

由于这是相同的,您可以明确保证,不仅返回的值在各个版本中都相同,而且您可以使用此算法自己可靠地计算出相同的值。

但是,我找不到任何类似的 SecureRandom 保证,并且由于 Random 说子类可以自由地打破这个规则,所以不能保证它会版本之间保持一致。我能找到的唯一证据是 a forum post有人观察到它产生了不一致的值(value)。根据Ian McLaird's answer , SecureRandom 似乎在实践中生成了一致的值,因此您可能会认为值得冒险假设它会起作用。但是,这种行为似乎并不能得到保证。

要回答您问题的第二部分,理论上他们可以更改它。但是,由于它目前是一个定义明确的操作,并且考虑到 Oracle 努力避免破坏向后兼容性,我认为这不太可能发生。

关于java - 具有跨不同 Java 版本的恒定种子的 Random 的可靠性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33171295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com