我有这个指纹用于字符串s, f(s)=(S [1] r ^ m-1)xor(S [2] r ^ m-2)xor ....(xor S [n] r ^ 0))mod(2 ^ 32) 我们只包含a和b(分别为0,1)。
如果是添加而不是xor那么它会很容易。我们可以使用以下规则解决它: (a + b)mod m =((mod m)+(b mod m))mod m,但在这种情况并非如此。 所以,任何想法都要记住,我无法计算,例如r ^ m-1因为我可能面临整数溢出。
答案 0 :(得分:2)
如果问题是溢出,我建议使用BigInteger
假设你有足够的内存,这不会溢出:
算术运算的语义完全模仿Java的语义 整数算术运算符,如Java语言中所定义 规格。例如,除以零会抛出一个 ArithmeticException,将负数除以正数得到a 负(或零)余数。 Spec中的所有细节 关于溢出被忽略,因为BigIntegers被制作得那么大 为了适应行动的结果所必需的。
BigInteger不是真正的类型。这是一堂课。这是一个包装类 旨在为您提供与int相同的功能,但允许您 使用尽可能大的数字而不必担心溢出。
类型会溢出,因为它们只是几个字节(确切地说 数量取决于内存的类型),一旦少量 内存溢出,数字也是如此。
没有类“溢出”,除非它是专门设计的(或 如果你的资源用完了)。定义一个具有足够内存的类 它包含的所有内容,主要是对其他内容的引用 类或其他数据结构。
答案 1 :(得分:1)
溢出不是问题,因为:
mod 2^32
的最终操作掩盖了更高位只需使用long
来保存结果(64位,因此第31位不会导致符号问题)。
答案 2 :(得分:0)
Java BigInteger
类不支持提升类型为BigInteger
的指数。你可以做的是使用Exponentiation by Squaring实现一个算法来自己计算能力。这些通常以递归算法的形式出现,它将计算你的能力,而不是实际将数字增加到超过指数2
(因此是平方)。
然而,Java BigInteger
类确实处理了溢出问题。
答案 3 :(得分:0)
等等......如果m只是S的长度,那就更简单了:
int re = 1;
int sig = 0;
for (int i=m-1; i>=0; --m) {
if (s[i] != 0)
sig ^= re;
re = (re*r) & 0xffffffff;
}
这对我来说似乎太简单了;你确定你的表达方式正确吗?
(我原来的回答:
如果您还没有整数指数函数,请从它开始:
/**
* Return x^e, mod 2^32
*/
unsigned int
iExp(unsigned int x, unsigned int e)
{
unsigned int rval = 1;
while (e > 0) {
if ((e & 1) != 0)
rval *= x;
x *= x;
e >>= 1;
}
return rval & 0xffffffff;
}
如果S是0或1值的数组,那么对于子表达式的其余部分,它实际上是一个“use”/“do not use”标志:
// I've taken the liberty of indexing S starting at 0 instead of 1
// compute f(s) = (S[0]r^m-1) xor (S[1]r^m-2) xor....(xor S[m-1]r^0)) mod (2^32)
int rval = 0;
for (x : S) {
--m;
if (x != 0)
rval ^= iExpr(r, m);
}
我没有测试过这个(我没有任何测试向量),但是应该这样做。