java - Java 中使用无符号整数的非加密哈希

标签 java hash

我正在寻找一个可以在 Java 中用于非加密目的的哈希函数。挑战在于大多数哈希函数返回有符号整数值(-、0、+),这些值不能在每个上下文中用作标识符(例如负整数不能在 URL 中使用)。这个问题的一个解决方案是我想出的是使用 32 位有符号 int 并将其转换为 32 位无符号 int 并将其存储在 long 中。这效果非常好。然而,32 位随机信息使得哈希冲突在我们的设置中过于频繁。解决此问题的一种方法是使用 64 位哈希函数(相同的 SipHash 也可以正常工作),并通过右移 1 并在 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();
    }

位移:

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

我缺少什么以及如何将 62 位无符号整数哈希值存储在 Java 中的 64 位 int(long)中?

更新1:

经过一些研究,我终于找到了一种正确显示 >>> 对 Long 值的效果的方法:

        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

最佳答案

a >> b

将 a 右移 b 位。在左侧,它重复已经存在的位(符号扩展!)。 示例:

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

a >>> b

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

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

关于java - Java 中使用无符号整数的非加密哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43080638/

相关文章:

java - Xpath 在 Chrome 浏览器中工作,但相同的 Xpath 在 Firefox 浏览器中不工作

JAVA OOD问题

java - Eclipse 上 java 中的 @Subscribe 和 @Produce 关键字

JAVA Arraylist 意外输出

json - 无法将字符串映射转换为 json

ruby - 如何对具有最高特定值的哈希进行排序?

java - 使用滚动 Pane

perl - 如何使用 key 将一个 Perl 散列转换为另一个?

出现提示时,使用 OpenSSL 的 Facebook SDK 的 Android key 哈希生成未设置为 android

使用散列密码的 PHP 登录