【发布时间】:2019-09-27 21:10:03
【问题描述】:
我正在尝试为 java.util.Random setSeed 和 next 函数创建一个反函数。本质上,我希望能够输入一个长值(在它被截断为 48 位之前)并取回一个种子或种子族,这将导致第一个 nextLong() 调用的该值。其相关源码如下:
setSeed(长种子)
seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1)
下一个(整数位)
//this function is called by nextLong()
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
问题似乎是因为第二部分,因为整数在乘法后溢出。因此,我不能简单地将常数分开,因为它最终会得到不同的结果,并且不会给我正确的种子。
我在二元运算方面不是很有经验,我想知道是否有办法在除法时解决这种溢出问题以获得正确的种子,而不必猜测真正的大后乘数实际上是多少。
【问题讨论】:
-
它不仅溢出,而且截断的结果还被屏蔽掉了它的 16 个最高有效位。
-
可能会计算出一个种子,它会产生特定的
long作为第一个结果,但这将取决于nextLong()计算的更完整细节。 -
看看this question,它提出了一个非常相似的问题。
-
nextLong()使用来自对底层 LCG 的两次连续调用的 32 位,每个状态只占用中间的 32 位。从密码学意义上来说,解决它可能并不“难”,但我认为这也不是微不足道的。 -
可能更多的是一个数学问题,如果你在这里没有得到答案,试试 math.stackexchange.com。
标签: java math binary integer-overflow