32位数的反向乘法

时间:2014-03-21 19:53:06

标签: hash bit-manipulation

我有两个大的带符号的32位数字(java整数)相乘,这样它们就会溢出。实际上,我有一个数字和结果。我可以确定其他操作数是什么吗?

knownResult = unknownOperand * knownOperand;

为什么呢?我有一个字符串,后缀用fnv1a进行哈希处理。我知道结果哈希和后缀,我想看看确定原始字符串的哈希是多么容易。

这是fnv1a的核心:

hash ^= byte
hash *= PRIME

4 个答案:

答案 0 :(得分:4)

这取决于。如果乘数是偶数,则必然至少丢失一位。所以我希望素数不是2。

如果它是奇数,那么你绝对可以反转它,只需乘以乘数的modular multiplicative inverse来撤消乘法。

有一种算法可以计算模块乘法逆模在Hacker's Delight中的2的幂。

例如,如果乘数为3,那么您需要乘以0xaaaaaaab来撤消(因为0xaaaaaaab * 3 = 1)。对于0x01000193,反之为0x359c449b

答案 1 :(得分:1)

你想要解决y = prime * x的等式x,你可以通过有限环模2 32 x = y / prime中的除法来实现。

从技术上讲,你可以通过将y乘以素数2 32 multiplicative inverse来实现,这可以通过extended Euclidean algorithm来计算。

答案 2 :(得分:0)

呃,师?或者我不理解这个问题?

答案 3 :(得分:0)

这不是最快的方法,但很容易记住的是:

unsigned inv(unsigned x) {
  unsigned xx = x * x;
  while (xx != 1) {
    x *= xx;
    xx *= xx;
  }
  return x;
}

返回x**(2**n-1)(如x*(x**2)*(x**4)*(x**8)*...x**(1+2+4+8+...))。正如循环退出条件所暗示的那样,x**(2**n)足够大时n为1,假设x为奇数。

因此,x**(2**n-1)等于x**(2**n)/x等于1/x等于将x乘以得到值1(mod 2 ** n)的事物。然后你申请:

knownResult = unknownOperand * knownOperand
knownResult * inv(knownOperand) = unknownOperand * knownOperand * inv(knownOperand)
knownResult * inv(knownOperand) = unknownOperand * 1

或简单地说:

unknownOperand = knownResult * inv(knownOperand);

但是有更快的方法,如其他答案所示。这个很容易记住。

此外,强制性SO“使用库函数”答案:BN_mod_inverse()