【问题标题】:Is there a simple way to invert an integer function that experiences overflow?有没有一种简单的方法来反转经历溢出的整数函数?
【发布时间】: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


【解决方案1】:

想知道你真正想要的是一个随机数生成器,其中生成的第一个数字是一个特定的值。

class MyRandom extends java.util.Random {
    long targetValue;
    long offset;
    int count=0;

    public MyRandom(long target) {
        this.targetValue = target;
   } 

   public long nextLong() {
        long rnd = super.nextLong();
        if(count++==0) {
            offset = target - rnd;
        }
        return rnd + offset;
   }
}

在第一次调用 nextLong 时,它将设置偏移量并返回目标。 在所有调用中,它将返回移动了固定数量的随机数。这应该给出均匀分布。

【讨论】:

  • 谢谢,但不,我想要一种方法来控制专门用于 java.util.Random 中内置的 RNG 的第一个输出
猜你喜欢
  • 2020-12-02
  • 2015-04-15
  • 2020-10-18
  • 1970-01-01
  • 2013-12-21
  • 2019-07-21
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多