私は、バイナリデータ用のhashCodeを作成するポータブルアルゴリズムを探しています。バイナリデータは非常に長くありません - 私はAvro
- kafka.KeyedMessages
で使用するための符号化キーです - おそらく長さは2〜100バイトですが、ほとんどのキーは4〜8バイトの範囲です。バイナリデータ用の移植可能なhashCodeの実装
これまでのところ、データを16進文字列に変換し、hashCode
を実行することをお勧めします。私はScalaとJavaScriptの両方でその作業を行うことができます。私はb: Array[Byte]
を定義したと仮定すると、Scalaは次のようになります。
b.map("%02X" format _).mkString.hashCode
それはJavaScript
にもう少し手の込んだだ - 幸いにもsomeone already ported JavaScriptに基本のhashCodeアルゴリズム - しかし、ポイントはHex
を作成できることです文字列は、バイナリデータを表すために、私はハッシュアルゴリズムが同じ入力をオフに動作することを確認することができます。
一方、hashCodeを作成するために、オリジナルの2倍のサイズのオブジェクトを作成する必要があります。幸運なことに、私のデータの大部分は小さいですが、これを行うにはより良い方法が必要です。
データを16進数の値にパディングするのではなく、バイナリデータをストリングに変換してバイナリデータと同じバイト数にすることができます。それはすべて文字化けし、印刷可能な文字よりも制御文字が多いですが、それでも文字列になります。あなたは移植性の問題に遭遇しますか?などエンディアン、Unicodeの、あなたがこれまで読んだ本を持って、すでにこれを知っていない場合
ところで、 - あなただけで行うことはできません。
val b: Array[Byte] = ...
b.hashCode
幸いにも私はすでに私の前にいることを知っていました私は早い時期にそれに遭遇したので、開始した。与えられた最初の回答に基づいて
更新
、java.util.Arrays.hashCode(Array[Byte])
は、トリックを行うだろうと最初に顔を赤らめるに表示されます。しかし、javadocの追跡に従えば、リストのアルゴリズムとbyte
のアルゴリズムに基づくアルゴリズムの背後にあるアルゴリズムであることがわかります。
int hashCode = 1;
for (byte e : list) hashCode = 31*hashCode + (e==null ? 0 : e.intValue());
あなたが見ることができるように、それはやっているすべての値を表すLong
を作成しています。特定のポイントでは、数値が大きくなりすぎて折り返します。これはあまり移植性がありません。私はそれがJavaScriptのために働くことができますが、npm
モジュールlong
をインポートする必要があります。そうした場合、それは次のようになります。
function bufferHashCode(buffer) {
const Long = require('long');
var hashCode = new Long(1);
for (var value of buff.values()) { hashCode = hashCode.multiply(31).add(value) }
return hashCode
}
bufferHashCode(new Buffer([1,2,3]));
// hashCode = Long { low: 30817, high: 0, unsigned: false }
、データがラップアラウンドしたときに、私はなぜわからないけれども、あなたは、並べ替えの、同じ結果を得るのですか。 Scalaで:
java.util.Arrays.hashCode(Array[Byte](1,2,3,4,5,6,7,8,9,10))
// res30: Int = -975991962
結果がIntであることに注意してください。 JavaScriptでは:
bufferHashCode(new Buffer([1,2,3,4,5,6,7,8,9,10]);
// hashCode = Long { low: -975991962, high: 197407, unsigned: false }
だから私は、low
バイトを取るとhigh
を無視する必要がありますが、そうでない場合、私は同じ結果を得ます。
もし移植が必要なら、md5のようなものを使うべきではないですか?あなたが言及したすべての言語でmd5のAPI /実装が必要ですか? – DavidS
またはより広範に[いくつかの高速非暗号化ハッシュ](http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed)。 – DavidS