在不同版本的Java中使用常量种子随机的可靠性

Jon*_*tre 8 java random

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

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

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

虽然我知道不能保证这对于Java的后续版本也是如此,并且第二个问题应该征求一些意见,你认为未来的Java版本将改变用于生成伪随机的算法的可能性是什么?使用Random和SecureRandom的数字?

谢谢!

res*_*man 9

是的,Random所有版本都通过Java 8保证这一点.SecureRandom但是,似乎没有任何类似的保证.

如果你看看随机的Javadocs,你可以看到:

如果使用相同的种子创建两个Random实例,并且对每个实例都进行相同的方法调用序列,则它们将生成并返回相同的数字序列.为了保证此属性,为Random类指定了特定的算法.为了Java代码的绝对可移植性,Java实现必须使用此处显示的所有算法用于Random类.但是,Random类的子类允许使用其他算法,只要它们遵守所有方法的一般合同即可.

强调我的.因此,一些想法明确地给出了这个问题,并且决定在类的文档中指定底层算法.理论上人们可以提供不同的实现,但是它不符合Java规范.

有关进一步的证据,请查看版本之间的实现.例如,该next方法在每个版本中都以完全相同的方式定义,因为至少Java 1.4(早在我看来).

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

由于这是相同的,因此您可以清楚地保证,不仅版本之间返回的值相同,而且您可以使用此算法自行计算相同的值.

但是,我找不到任何类似的保证SecureRandom,并且因为Random说子类可以自由地破坏这个规则,所以它不能保证它们在版本之间是一致的.我能找到的唯一证据就是观察用它生成不一致值的人的论坛帖子.根据Ian McLaird的回答,SecureRandom在实践中似乎确实产生了一致的价值观,所以你可能会认为假设它可行的风险是值得的.但是,似乎无法保证此行为.

要回答你问题的第二部分,理论上他们可能会改变它.但是,由于它目前是一个定义明确的操作,并且鉴于Oracle在避免向后兼容性方面的工作有多么困难,我认为这是非常不可能的.