2017-11-12 6 views
1

Javaで一連の文字列のハッシュを計算したいと思う。はい、私は文字列をソートし、digest.updateを使用して MD5ハッシュ反復を計算することができます。 しかし、私は、ソートを省略してcombineUnorderedhttps://github.com/google/guava/wiki/HashingExplained のようなものを使用することを好むがあり、このようなOrder-independant Hash Algorithm と同じを求めて同様の質問がたくさんあるが、それらの非Javaで反復順序の独立したハッシュを計算する方法を示す簡単な例を提供します。Javaで独立したハッシュを注文する

+0

youneedがセットのハッシュアルゴリズムを上書きするために行う理由? –

+0

@SzigyártóMihály上書きする必要はありません、私は簡単な例を探しています。私はMD5を知っています。これは注文に敏感で、MurmurHashは使用すべきではありませんが、使用例が見つかりませんでした。 –

+0

セットはアイテムのハッシュの合計を使用しますが、順序に依存しません。 –

答えて

3

だけXOR各ハッシュと順序は重要ではありません。さらに、ハッシュサイズはコレクションのサイズとともに大きくなるのではなく固定されます。 Java文字列のハッシュコードに組み込まれた使用

ハッシュコード:

int hashcode = strings.stream() 
     .mapToInt(Object::hashCode) 
     .reduce(0, (left, right) -> left^right); 

ハッシュコード尋ねた質問のようにグアバとMD5を使用して:

Optional<byte[]> hash = strings.stream() 
     .map(s -> Hashing.md5().hashString(s, Charset.defaultCharset())) 
     .map(HashCode::asBytes) 
     .reduce((left, right) -> xor(left, right)); 


static byte[] xor(byte[] left, byte[] right) { 
    if(left.length != right.length) { 
     throw new IllegalArgumentException(); 
    } 
    byte[] result = new byte[left.length]; 
    for(int i=0; i < result.length; i++) { 
     result[i] = (byte) (left[i]^right[i]); 
    } 
    return result; 
} 
+0

これが望ましい方法です。ハッシュを排他的論理和(XOR)することは、それらを追加する方がよい。 –

+0

@ Magnusありがとう私は 'XOR'を試してみます。 –

1

各文字列のMD5ハッシュを個別に計算し、それらをすべて追加して1つのハッシュを得ることができます。それは順序に依存しないでしょう。加算演算は可換であるためです。ここ

は、(我々が与えられた文字列のMD5ハッシュを計算し、16進形式で結果を返すメソッドmd5Hex(文字列str)を有すると仮定した場合)の例である:

String[] strings = {"str1", "str2", "str3", ...}; 

BigInteger hashSum = BigInteger.ZERO; 
for(String s : strings) { 
    String hexHash = md5Hex(s); 
    hashSum = hashSum.add(new BigInteger(hexHash, 16)); 
} 

String finalHash = hashSum.toString(16); 
+0

はい、ありがとうございます。質問の背景(downwotedでも)は、このようにしなければならないか、ソートされていない可能性の高いものを組み合わせることができる代替ハッシュアルゴリズムを使用して衝突を少なくします。 –

+0

@MarmiteBomberは、例を追加しました。 – elyor

関連する問題