如何实现此签名?

时间:2013-04-29 18:51:07

标签: java fingerprint

我有这个指纹用于字符串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因为我可能面临整数溢出。

4 个答案:

答案 0 :(得分:2)

如果问题是溢出,我建议使用BigInteger假设你有足够的内存,这不会溢出:

javadoc

  

算术运算的语义完全模仿Java的语义   整数算术运算符,如Java语言中所定义   规格。例如,除以零会抛出一个   ArithmeticException,将负数除以正数得到a   负(或零)余数。 Spec中的所有细节   关于溢出被忽略,因为BigIntegers被制作得那么大   为了适应行动的结果所必需的。

SO explaning overflow

  

BigInteger不是真正的类型。这是一堂课。这是一个包装类   旨在为您提供与int相同的功能,但允许您   使用尽可能大的数字而不必担心溢出。

     

类型会溢出,因为它们只是几个字节(确切地说   数量取决于内存的类型),一旦少量   内存溢出,数字也是如此。

     

没有类“溢出”,除非它是专门设计的(或   如果你的资源用完了)。定义一个具有足够内存的类   它包含的所有内容,主要是对其他内容的引用   类或其他数据结构。

答案 1 :(得分:1)

溢出不是问题,因为:

  • XOR是一种bitwuse操作(高位的存在/不存在会影响结果)
  • 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);
}

我没有测试过这个(我没有任何测试向量),但是应该这样做。