2017-03-28 14 views
0

Javaで非暗号化目的で使用できるハッシュ関数を探しています。問題は、ほとんどのハッシュ関数がすべてのコンテキストで識別子として使用できない符号付き整数値( - 、0、+)を返すことです(例えば、負の整数はURLでは使用できません)。この問題の解決策の1つは、32ビットの符号付きintを使用して32ビットのunsigned intに変換してlongに格納することです。これはかなりうまくいく。しかし、32ビットのランダム情報は、私たちの設定ではハッシュ衝突を頻繁に起こします。これを解決する1つの方法は、64ビットのハッシュ関数(同じSipHashが機能します)を使用して、符号付き整数を符号なしに変換し、右にシフトしてMSBの位置に0を設定することです。私はJava >>演算子でそれを達成しようとしていましたが、結果は意味をなさない。符号なし整数を使用した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に格納されている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

?また、 '' '(符号付き右シフト)ではなく、' '>>>'(http://stackoverflow.com/questions/2811319/difference-between-and)(符号なし右シフト)を試してください。 –

+0

@ElliottFrischありがとう!/-123123 /が/ 123123 /と酷似しているため、この値に基づいたルーティングがあり、それが否定的であることをサポートしていないためです。 – Istvan

答えて

2

a >> b

右にシフト:

私は最終的に正しくロング値に>>>の効果を表示する方法が見つかったいくつかの研究を行った後bビット分。左にはすでにあるビットが繰り返されます(符号が伸びます)。 例:

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

a >>> b

も、Bビットだけ右にシフトするが、署名しません延長する。それは、常に左側にゼロに追加します。

  • 101010 >>> 1 = 010101
  • 010101 >>> 1 = 001010 URLで負の値を使用することはできませんなぜ
関連する問題