【问题标题】:Similar to hash values but something that returns an int类似于哈希值,但返回一个 int
【发布时间】:2012-01-22 17:54:45
【问题描述】:

对字符串使用哈希函数 MD5 会创建一个非常长的值,并且每次都会为同一个字符串创建相同的值。现在,我的问题是:有没有办法做类似的事情,比如给它一个字符串,它每次返回相同的整数,而且它为不同字符串返回的整数在特定的间隔内。我的意思是类似于this

例如:给它“玛丽有一只小羊羔”。它返回值 10。给出相同的字符串,它再次返回 10。

请务必询问,以防我不完全清楚。

【问题讨论】:

  • 请注意,它不会是唯一的。
  • 即使字符串是唯一的?其实就算没有,有这个功能吗?
  • 有 2^32 个可能的整数。有无数个可能的字符串。 怎么想?

标签: firefox hash firefox-addon dht


【解决方案1】:

您正在描述“哈希函数”。在维基百科上查找。

MD5 是一种哈希函数。大多数 MD5 实现返回一个字符串,但该字符串只是一个(大)整数的表示。您可以获取 MD5 哈希,然后根据需要使用尽可能多的低位来获得所需大小的整数。如果所需范围不是 2 的幂,则需要进行模运算以使其进入所需范围。

此外,几乎每一种现代编程语言都有一个用于散列字符串的内置函数,该函数返回一个整数。在 Java 中,它是 String.hashCode()。在 Ruby 中,它是 String#hash。

在这种情况下,语言是 Javascript,它(我很震惊地学习)似乎没有内置这样的东西。这是来自 Java 平台的 String.hashCode() (也许你可以将它移植到Javascript):

public int hashCode() {
int h = hash;
if (h == 0) {
    int off = offset;
    char val[] = value;
    int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

【讨论】:

  • "您可以获取一个 MD5 散列,然后根据需要使用尽可能多的低位来获得所需大小的整数。"你能详细说明一下吗?如果可能的话,一个简单的例子会很棒。 (另外,通过“使用尽可能多的低阶位”,它不会使它不是唯一的吗?)
  • 嗯,我认为该函数将唯一键映射到唯一字符串。不同的字符串,不同的键。 “失败”率太低而无法显着。
  • 哈希必然不是唯一的,正如@SLaks 解释的那样。不过,整个想法是“冲突”(2 个字符串获得相同数字)的可能性应该非常小。如果您使用 32 位整数来保存哈希,则最多有 2^32 个可能的哈希值。如果散列算法很好,那么获得其中任何一个值的机会应该大致相等。因此,对于 2 个任意字符串,获得相同哈希值的机会应该是 2^32 中的 1。如果您使用 64 位作为哈希值,那么……您可能永远不会在宇宙的预期生命周期内发生碰撞。
  • 安德烈,你用的是什么语言?只需使用内置函数来散列字符串,无论它是什么。它将唯一的字符串映射到唯一的键“故障率太小以至于不重要”。 (最后一句话很重要。)
  • 我正在为 mozilla firefox 开发一个扩展。语言是 javascript,但我可以使用 firefox 平台上的 C++ 类。我正在尝试使用 Chord 协议,在该协议中我需要对节点(计算机)的 ip+端口进行散列,然后将它们(或至少将它们视为已放置)放置在 ASCENDING FASHION 中的一个圆圈上。我需要能够比较它们之间的哈希值,从而知道将它们放在圆圈的哪个位置。
【解决方案2】:

您可以使用 MD5 哈希的低字节。您必须考虑 JavaScript(至少在 Firefox 9 中)可以使用 48 位(6 字节)来存储精确的整数,另一方面,MD5 哈希的长度是 128 位(16 字节)。因此,与 MD5 相比,您必然会遇到更多的哈希冲突。但还是:

function toHashCode(str)
{
  // Convert string to an array of bytes
  var array = Array.prototype.slice.call(str);

  // Create MD5 hash
  var hashEngine = Components.classes["@mozilla.org/security/hash;1"]
                             .createInstance(Components.interfaces.nsICryptoHash);
  hashEngine.init(hashEngine.MD5);
  hashEngine.update(array, array.length);
  var hash = hashEngine.finish(false);

  // Turn the first 6 bytes of the hash into a number
  var result = 0;
  for (var i = 0; i < 6; i++)
    result = result * 256 + hash.charCodeAt(i);
  return result;
}

alert(toHashCode("test"));  // Displays 265892827251497
alert(toHashCode("Mary had a little lamb."));   // Displays 117938552300214

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    相关资源
    最近更新 更多