次のプロパティを持つ Java の特殊なハッシュ関数 h(X,Y) が必要です。
- X と Y は文字列です。
- h(X,Y) = h(Y,X)。
- X と Y は任意の長さの文字列であり、h(X,Y) の結果にも長さ制限はありません。
- X が A と等しくなく、Y が B と等しくない場合、h(X,Y) と h(Y,X) は h(A,B) = h(B,A) と衝突してはなりません。
- h() は、前述の要件を満たす必要がない限り、安全なハッシュ関数である必要はありません。
- かなり高いパフォーマンスですが、これは制限のない基準です。
私の考えでは、要件 2 と要件 4 は少し矛盾していると思いますが、心配しすぎているのかもしれません。
現在、私がJavaで行っていることは次のとおりです。
public static BigInteger hashStringConcatenation(String str1, String str2) {
BigInteger bA = BigInteger.ZERO;
BigInteger bB = BigInteger.ZERO;
for(int i=0; i<str1.length(); i++) {
bA = bA.add(BigInteger.valueOf(127L).pow(i+1).multiply(BigInteger.valueOf(str1.codePointAt(i))));
}
for(int i=0; i<str2.length(); i++) {
bB = bB.add(BigInteger.valueOf(127L).pow(i+1).multiply(BigInteger.valueOf(str2.codePointAt(i))));
}
return bA.multiply(bB);
}
これは恐ろしいことだと思いますが、それがより良い解決策を探している理由です。ありがとう。
OS X 10.7 で 8GB RAM と Java 1.6 を搭載した 2.53GHz デュアル コア Macbook Pro では、ハッシュ関数は 2 つの 8 (ASCII) 文字列に対して約 270 マイクロ秒かかります。文字列のサイズが大きくなったり、Unicode 文字が使用されたりすると、これは高くなると思います。