【问题标题】:Scala MurmurHash3 library not matching Python mmh3 libraryScala MurmurHash3 库与 Python mmh3 库不匹配
【发布时间】:2017-01-03 16:51:13
【问题描述】:

我需要在 Python 和 Scala 中对字符串进行 MurmurHash。然而,他们给出了非常不同的结果。 Scala 的内置 MurmurHash3 库似乎没有提供与我尝试过的任何其他库(包括在线库)相同的结果。奇怪的是它似乎匹配单个字符而不是多个字符。以下是一些示例:

Python:

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

斯卡拉:

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

我已经尝试过使用有符号和无符号整数,因为我知道 Java 已经签名,并且 python 正在包装的 C 实现正在使用无符号。但即使使用 NumPy 转换为带符号的 int 也无济于事。这个网站似乎同意python实现:

http://murmurhash.shorelabs.com/

关于这里可能发生什么的任何想法?

【问题讨论】:

    标签: python scala encryption hash murmurhash


    【解决方案1】:

    Scala 使用编码为 UTF-16 的 Java 字符串。它们一次打包两个到Int; Python 使用char*(8 位),因此一次包含四个字符而不是两个。

    编辑:Scala 还按 MSB 顺序打包字符,即(s.charAt(i) << 16) | (s.charAt(i+1))。如果获得完全相同的答案真的很重要,您可能需要切换到一系列短裤,然后交换每一对短裤。 (或者将 Scala 代码移植到 Python,反之亦然。)它还以字符串长度结束;我不确定 Python 是如何合并长度数据的,如果有的话。 (这很重要,因此您可以区分字符串"\u0000" 和"\u0000\u0000"。)

    【讨论】:

    • 那么,如果这是问题所在,在 python 中将“字符串”转换为 utf-16 会不会返回与 Scala 相同的结果?蟒蛇是:'string'.encode('UTF-16')
    • @patrickbarker - 仅当 Python 不打包任何其他数据,并且在组合字符时按 MSB 顺序打包字符(短裤),因为这是 Scala 实现所做的。
    【解决方案2】:

    这是由于 Scala 的 MurmurHash3.stringHash 和 MurmurHash3.bytesHash 的实现方式不同

    MurmurHash3.bytesHash 和 python 的 mmh3.hash 以 4 个一组将字符传递给哈希混合器,但 MurmurHash3.stringHash 以 2 个一组混合字符。这意味着两个哈希函数返回完全不同的输出:

    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 值的结果完全匹配:

    我建议第一个选项,特别是如果您的用例需要更好的性能,或者您需要散列大量字符串

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 2013-09-12
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      相关资源
      最近更新 更多