Java中的非加密散列使用无符号整数

时间:2017-03-28 21:55:00

标签: java hash

我正在寻找可用于Java中的非加密目的的散列函数。挑战在于大多数散列函数返回有符号整数值( - ,0,+),这些值不能在每个上下文中用作标识符(例如,不能在URL中使用负整数)。这个问题的一个解决方案是我想出的是使用32位signed int并将其转换为32位unsigned int并将其存储在long中。这非常有效。但是,32位随机信息使哈希冲突在我们的设置中过于频繁。解决此问题的一种方法是使用64位散列函数(相同的SipHash工作正常)并通过将一个向右移位并在MSB位置具有0来将该有符号整数转换为无符号整数。我试图通过Java>>实现这一目标。运算符,但结果没有意义。

//Using Guava
private final static HashFunction hashFunction = Hashing.sipHash24();

    private static int getRandomInt() {
        return hashFunction.newHasher().putLong(rnd.nextLong()).hash().asInt();
    }

    private static long getRandomLong(){
        return hashFunction.newHasher().putLong(rnd.nextLong()).hash().asLong();
    }

Bitshifting:

 System.out.println(Long.toBinaryString(-2147483648L >> 1));
 1111111111111111111111111111111111000000000000000000000000000000

我缺少什么,如何在Java中以64位int(long)存储62位无符号整数散列值?

UPDATE1:

经过一番研究后,我终于找到了一种正确显示>>>效果的方法。在长值上:

        System.out.println(
          String.format("%64s", Long.toBinaryString(-2147483648L))
            .replace(' ', '0'));
        System.out.println(
          String.format("%64s", Long.toBinaryString(-2147483648L >>> 1))
            .replace(' ', '0'));

        1111111111111111111111111111111110000000000000000000000000000000
        0111111111111111111111111111111111000000000000000000000000000000

1 个答案:

答案 0 :(得分:2)

a >> b

向右移动b位。在左边,它重复已经存在的位(符号延伸!)。 例子:

  • 101010>> 1 = 110101
  • 010101>> 1 = 001010

a >>> b

也将a向右移位b位,但不进行符号扩展。它总是在左边添加零:

  • 101010>>> 1 = 010101
  • 010101>>> 1 = 001010