Jenkins one_at_a_time hash - 试图让 Python 代码重现 JavaScript 代码

Posted

技术标签:

【中文标题】Jenkins one_at_a_time hash - 试图让 Python 代码重现 JavaScript 代码【英文标题】:Jenkins one_at_a_time hash - trying to Make Python Code reproduce JavaScript code 【发布时间】:2022-01-07 16:07:17 【问题描述】:

我从another post recently 借用了这段代码,它非常适合我的需求...... 但是我试图从 Python 代码中重现相同的结果,所以这两个语言函数一致,我一直在努力……到目前为止,这两个没有产生我需要的相同结果……我怀疑这是一个问题在 Python 与 javascript 中使用无符号整数。

JavaScript 代码:

//Credits (modified code): Bob Jenkins (http://www.burtleburtle.net/bob/hash/doobs.html)
//See also: https://en.wikipedia.org/wiki/Jenkins_hash_function
//Takes a string of any size and returns an avalanching hash string of 8 hex characters.
function jenkinsOneAtATimeHash(keyString)

  let hash = 0;
  for (charIndex = 0; charIndex < keyString.length; ++charIndex)
  
    hash += keyString.charCodeAt(charIndex);
    hash += hash << 10;
    hash ^= hash >> 6;
  
  hash += hash << 3;
  hash ^= hash >> 11;
  //4,294,967,295 is FFFFFFFF, the maximum 32 bit unsigned integer value, used here as a mask.
  return (((hash + (hash << 15)) & 4294967295) >>> 0).toString(16)
;

Python 代码:

def calcuulateChecksum(keyString: str):
    # Credits(modified code): Bob Jenkins (http://www.burtleburtle.net/bob/hash/doobs.html)
    # See also: https://en.wikipedia.org/wiki/Jenkins_hash_function
    # Takes a string of any size and returns an avalanching hash string of 8 hex characters.
    hash = 0
    # for (charIndex = 0; charIndex < keyString.length; ++charIndex):
    for char in keyString:
        hash += ord(char.encode("utf-8"))
        hash &= 0xFFFFFFFF
        hash += hash << 10
        hash &= 0xFFFFFFFF
        hash ^= hash >> 6
        hash &= 0xFFFFFFFF
    hash += hash << 3
    hash &= 0xFFFFFFFF
    hash ^= hash >> 11
    hash &= 0xFFFFFFFF
    hash += hash << 15
    hash &= 0xFFFFFFFF
    # # 4,294,967,295 is 0xffffffff, the maximum 32 bit unsigned integer value, used here as a mask.
    return hex((hash & 4294967295))

任何有关使 Python 代码与 JavaScript 函数匹配的帮助将不胜感激... 另一方面,我认为 Python 代码与 Wiki 中显示的结果匹配,那么为什么 JavaScript 代码不匹配呢?

【问题讨论】:

我不完全确定我理解您为什么在单个字符上使用 .encode('utf8') 以及这是否有意义。也许您要编码整个字符串而不是单个字符?你能给出一个示例字符串,它们给出不同的结果吗? 不,我不能.. :) 这是我尝试让两种语言函数得出相同结果的一件事,因为某些字符可能或可能的位数需要被代表。我显然认为这不是问题。我觉得问题在于 JavaScript 如何允许 Python 似乎不允许的有符号整数。 【参考方案1】:

也许我只是想通了……只是不确定它为什么会起作用……如果我将 JavaScript 代码更改为仅使用无符号右移,它似乎会产生与 Python 相同的输出(和原始 C 代码)确实......我将不得不对一系列 keyString 值进行进一步测试。

function jenkinsOneAtATimeHash(keyString)

  let hash = 0;
  for (charIndex = 0; charIndex < keyString.length; ++charIndex)
  
    hash += keyString.charCodeAt(charIndex);
    hash += hash << 10;
    hash ^= hash >>> 6;
  
  hash += hash << 3;
  hash ^= hash >>> 11;
  //4,294,967,295 is FFFFFFFF, the maximum 32 bit unsigned integer value, used here as a mask.
  return (((hash + (hash << 15)) & 4294967295) >>> 0).toString(16)
;

【讨论】:

以上是关于Jenkins one_at_a_time hash - 试图让 Python 代码重现 JavaScript 代码的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 Angular 测试阶段出现以下问题:Chrome Headless has not capture in 60000 ms, kill

从 has_many 更改为 has_one 关系轨

如何在同一模型中进行 has_many 和 has_one 关联?

使用高效的 `has` 操作实现堆栈

Rails ActiveRecord 关联“has_many,每个都有 has_one”

has_and_belongs_to_many 或多态 has_many :through?