2016-08-26 4 views
5

私はPythonとScalaの両方でMurmurHash文字列を使う必要があります。しかし、彼らは非常に異なる結果を与えています。 Scalaの組み込みのMurmurHash3ライブラリは、私がオンラインのものを含めて試した他のライブラリと同じ結果を出すようには見えません。奇妙なことは、1文字にはマッチしているようですが、複数の文字にはマッチしていないようです。ここではいくつかの例は以下のとおりです。Scala MurmurHash3ライブラリがPython mmh3ライブラリと一致しません

のPython:

mmh3.hash('string', 0) 
res: -1390314837 

スカラ:

MurmurHash3.stringHash("string", 0) 
res: 379569354 

私はJavaが署名している知っているとCの実装のpythonがラッピングされているように私は、符号付きと符号なし整数型で遊んで試してみました署名なしを使用します。しかし、NumPyを使って符号付き整数に変換しても、私たちは助けにはならない。このウェブサイトはPython実装と一致しているようだ:

http://murmurhash.shorelabs.com/

ここで起こって何ができるか上の任意のアイデアを?

答えて

3

Scalaは、UTF-16としてエンコードされたJava文字列を使用します。これらは一度に2つずつIntにパックされます。 Pythonはchar*(8ビット)を使用しているため、一度に2つではなく4つの文字でパックします。

編集:Scalaはまた、MSBの順序で文字をパックします。つまり、(s.charAt(i) << 16) | (s.charAt(i+1))です。あなたは短所の配列に切り替える必要がありますし、正確に同じ答えを得ることが本当に重要な場合は、それらのすべてのペアをスワップする必要があります。 (あるいは、ScalaコードをPythonに移植するか、逆もまた同様です。)また、文字列の長さで終了します。 Pythonが長さデータをどのように組み込んでいるかわかりません。 (あなたは、文字列"\u0000""\u0000\u0000"を区別することができますので、これは重要です。)

+1

これが問題だった場合、Pythonの 'string'をutf-16に変換しないと、Scalaと同じ結果が返されますか? Pythonが: 'string'.encode( 'UTF-16')' – patrickbarker

+1

@patrickbarker - Pythonが他のデータをパックしていない場合にのみ、それらを組み合わせるときにMSB順に文字(short)をパックします。 Scalaの実装はそうです。 –

0

は、これは4のグループのハッシュミキサーにScalaのMurmurHash3.stringHashMurmurHash3.bytesHash

MurmurHash3.bytesHashとPythonのmmh3.hashパス文字間の実装の違いによるものです

import scala.util.hashing.MurmurHash3 

val testString = "FiddlyString" 

MurmurHash3.stringHash(testString)   /* Returns an int */ 
MurmurHash3.bytesHash(testString.getBytes()) /* Returns a different int */ 

ですから、PYTの結果が必要な場合:しかし、MurmurHash3.stringHashこれは2つのハッシュ関数が完全に異なる出力を返すことを意味し2のグループ内の文字をミックスほんと正確に一致するように、ScalaのMurmurHash3値:

  • 利用MurmurHash3.bytesHash(myString.getBytes())代わりのmmh3.hash()
  • 使用MurmurHash3.stringHashMurmurHash3.stringHash()私はScalaのMurmurHash3.stringHash

と互換性があるようにwc-duck's pure-python implementation of MurmurHash3から適応pymmh3.string_hash機能を持つ私は」特にユースケースがより良いパフォーマンスを必要とする場合、または大量の文字列をハッシュする必要がある場合は、最初のオプションを助言してください。

関連する問題