【问题标题】:Simple hash function (1 byte output from string input)简单的散列函数(从字符串输入输出 1 个字节)
【发布时间】:2009-12-28 17:29:33
【问题描述】:

我正在寻找一种简单的散列算法,它会给我一个字节的字符串输入输出(如果有帮助,输入将是 RFC822 电子邮件地址)。

我希望它简单、快速并放大输入差异(因此两个相似的地址具有不同的输出)。 (是的,我 am 在一个字节的输出中要求很多。)

理想情况下,我想要一个 XSL 答案,但我可以使用 Java 或 Javascript(然后将哈希作为参数传递给 XSL 处理器)。

谢谢。

【问题讨论】:

  • 如果你想要一个基于 XSLT 的解决方案,那么它是否产生 1 个字节真的很重要吗?

标签: java javascript xslt hash


【解决方案1】:

为什么不取标准字符串hashCode() 函数的最高/最低有效字节?

【讨论】:

  • 这应该可以作为 Java 解决方案,但我坚持使用 XSLT 解决方案。
【解决方案2】:

使用包含 9 位信息的 CRC-8,然后从两端删除一点,就这样结束了。否则使用任何其他常见的 CRC 算法。

【讨论】:

    【解决方案3】:

    每个哈希函数都有其优点和缺点,快速且易于计算的哈希函数往往对某些类别的数据表现不佳。反复试验需要成为任何解决方案的一部分。除了其他建议之外,您还可以尝试使用整数乘法作为哈希函数的一部分,例如

    hash = 0
    for (int i=0; i<data.length; i++)
        hash = ((37 * hash) + data[i]) & 0xff;
    

    【讨论】:

    • 这到底是做什么的?
    • @BernardoDalCorno:这只是几行代码片段,不是完整的可编译方法。哪个部分令人困惑?如果有帮助的话,我可以把它变成一种真正的方法。
    • 好吧,为什么要乘以 37 而不是 29?添加一个字符(不是另一个数字)时,结果会怎样? “&”运算符在做什么以及为什么使用 0xff(为什么不使用 255 而不是十六进制)?
    【解决方案4】:

    我的建议是简单地对字符串中的所有字节进行异或。每一个字节的每一位都会影响最终的结果,任何一个位的错误肯定会导致哈希不同。

    非常简单,非常快。考虑到结果位数很少,可能几乎与任何其他解决方案一样好。

    【讨论】:

    • 您可能想要更多,因为大多数电子邮件地址主要是小写 ascii,带有一个“@”和一个“.”;所以你只得到大约 5 位而不是 8 位的变化。
    • 我不认为这个问题过于简单化的前提证明了比这更多的努力。如果您在 31/32 (=96.9%) 或 255/256 (=99.6) 情况下检测到不同的地址真的很重要吗?
    • 简单异或的一个可能问题是它不受顺序影响,因此“abc”与“cba”具有相同的哈希值。但是 XOR 最终可能会像更痛苦的东西一样工作或更好,因为正如你所指出的,基本上不可能用 8 位输出做得很好。 XOR 方法将在 任何 个位位置中检测奇数个位错误,这是一个明确的优势。
    • 冒着过度设计的风险,我很想按照你的建议计算哈希的低阶 5 位,使用类似于我之前的方法但使用 hash3 = 的方法计算高阶 3 位((5 * hash3) + data[i]) mod 7 代替。这也应该能检测到大约 6/7 的乱序地址。
    • 如果一个位切换 0->1 和另一个 1->0,对于这样的修改字符串,您将获得相同的哈希值。所以“abcd”将与“acbd”具有相同的哈希值。
    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 2019-08-21
    • 2014-12-19
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多