【问题标题】:How many string characters should I read to get a good hash?我应该读取多少个字符串字符才能获得良好的哈希?
【发布时间】:2011-10-18 00:16:53
【问题描述】:

这里有一个小难题:如果您使用像 CRC-64 这样的哈希算法,那么需要读取字符串中的多少字节才能计算出好的哈希?假设您所有的字符串至少有 2 KB 长,那么使用整个字符串来计算缓存似乎是一种浪费或资源,但是您认为多少个字符就足够了?因为它等于 64 位,所以只有 8 个 ASCII 字符就足够了吗?使用超过 8 个 ASCII 字符不会毫无意义吗?我想知道你对此的看法。

更新: 对于“良好的哈希”,我的意思是通过使用更多字节来计算哈希冲突的可能性不会降低。

【问题讨论】:

    标签: hash crc crc64


    【解决方案1】:

    两个不同字符串的前 8 个字母相同的概率是多少?根据这些字符串是什么,它可能非常高,在这种情况下,您肯定会遇到哈希冲突。

    散列整个事情。几千字节不算什么。除非您确实需要在程序中节省纳秒,否则不散列完整的字符串将是过早的优化。

    【讨论】:

    • 如果我需要优化,那么如果我得到 8 个字节分布在整个字符串上怎么办。如果字符串是 8kb,那么我将获取每 KB 的第一个字节来传播生成哈希的字节。
    • 你真的需要优化吗?您是否正在实施硬件或驱动程序或其他东西?没有消费者应用程序需要这种优化。
    • 像你这样的程序员选择混淆实际情况而不是预先考虑是否有原因?而不是是/否,“也许”?您需要情境建议,但不会提供情境。就好像你故意选择浪费别人的时间,而不是为正确答案提供阻力最小的路径。
    • 对不起,先生。我无意冒犯您或以任何方式浪费您的时间。这是我用 C++ 编写的自定义 B+ 树散列算法。我回答“也许是”,因为我主要问的是好奇而不是必要性的问题。谢谢你的帮助。
    【解决方案2】:

    如果您在 8 字节或更少字节上使用 CRC-64,则使用 CRC-64 没有意义:只需“按原样”使用 8 字节即可。除非输入比预期输出长,否则 CRC 没有任何附加值。

    作为一般规则,如果您的哈希函数有 n 位的输出,那么一旦您累积了大约 2n/2 字符串。简而言之,如果您使用 64 位,那么您在前 20 亿个字符串中遇到冲突的可能性很小。如果您获得 160 位或更多的输出,那么冲突几乎是不可行的(与 CPU 着火等硬件故障相比,您遇到的冲突要少得多)。这假设哈希函数是“完美的”。如果你的散列函数从选择几个数据字节开始,那么,你所做的 not 选择的字节必然不会对散列输出产生任何影响,所以你最好使用“好”字节- 这完全取决于您要散列的字符串类型。这里没有一般规则。

    我的建议是首先尝试对整个字符串使用通用哈希函数;我通常推荐MD4。 MD4 是一个密码散列函数,已经被彻底破解了,但是对于一个不涉及安全的问题,它仍然非常擅长混合数据元素(从密码学上讲,CRC 比 MD4 坏得多)。据报道,MD4 在某些平台上实际上比 CRC-32 更快,因此您可以试一试。在一台基本的 PC(我的 2.4 GHz Core2)上,MD4 实现以大约 700 MBytes/s 的速度工作,所以我们说的是每秒 35000 个散列的 2 kB 字符串,这还不错。

    【讨论】:

    • 好的,所以 8 个字符对于生成哈希是没有意义的。但是如果我使用 32 个字符而不是 16 个字符,那么散列 more 是随机的 32 吗?随机性的好处在多少字符时消失?
    猜你喜欢
    • 2010-11-22
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    相关资源
    最近更新 更多