我需要在Python和Scala中使用MurmurHash字符串。然而,他们给出了截然不同的结果。Scala内置的MurmurHash3库似乎不能给出与我尝试过的任何其他库相同的结果,包括在线库。奇怪的是,它似乎只匹配一个字符,而不是多个字符。下面是一些示例:
Python:
mmh3.hash('string', 0)
res: -1390314837Scala:
MurmurHash3.stringHash("string", 0)
res: 379569354我尝试过使用有符号和无符号的int,因为我知道Java已经有了符号,而C实现python使用的是无符号的。但是,即使使用NumPy转换为带符号的整型,也无济于事。这个网站似乎同意python的实现:
http://murmurhash.shorelabs.com/
你知道这是怎么回事吗?
发布于 2016-08-27 13:59:50
Scala使用编码为UTF-16的Java字符串。它们一次打包两个到一个Int中;Python使用一个char* (8位),所以一次打包四个字符而不是两个字符。
编辑: Scala也会按照MSB的顺序打包字符,比如(s.charAt(i) << 16) | (s.charAt(i+1))。如果得到完全相同的答案真的很重要,你可能需要切换到一组短裤,然后每一条短裤都互换。(或者将Scala代码移植到Python,反之亦然。)它还以字符串长度结束;我不确定Python如何合并长度数据,如果它确实这样做的话。(这一点很重要,这样可以区分字符串"\u0000"和"\u0000\u0000"。)
发布于 2017-09-28 23:28:27
这是由于Scala的MurmurHash3.stringHash和MurmurHash3.bytesHash在实现上的不同
MurmurHash3.bytesHash和python的mmh3.hash将字符以4为一组传递给散列混合器,而MurmurHash3.stringHash以两组为一组混合字符。这意味着这两个散列函数返回完全不同的输出:
import scala.util.hashing.MurmurHash3
val testString = "FiddlyString"
MurmurHash3.stringHash(testString)           /* Returns an int */
MurmurHash3.bytesHash(testString.getBytes()) /* Returns a different int */因此,如果您需要python和Scala的MurmurHash3值完全匹配的结果:
为了与mmh3.hash()
MurmurHash3.stringHash兼容,
pymmh3.string_hash函数的MurmurHash3.bytesHash(myString.getBytes()),而不是MurmurHash3.stringHash()和MurmurHash3.stringHash() MurmurHash3.stringHash我建议使用第一种方法,特别是如果您的用例需要更好的性能,或者您需要散列大量的字符串
https://stackoverflow.com/questions/39176052
复制相似问题