C 的最小散列函数?

Posted

技术标签:

【中文标题】C 的最小散列函数?【英文标题】:A minimal hash function for C? 【发布时间】:2010-10-19 03:21:37 【问题描述】:

我不能使用 boost:hash,因为我必须坚持使用 C 并且不能使用 C++。

但是,我需要对大量(10K 到 100k)令牌字符串(长度为 5 到 40 个字节)进行哈希处理,以便在这些字符串中进行最快的搜索。

MD5、SHA1 或任何长散列函数对于简单的任务来说似乎太重了,我不是在做密码学。另外还有存储和计算成本。

因此我的问题:

    在大多数实际情况下,可以确保防止冲突的最简单的哈希算法可能是什么。

    哈希值使用多少位?我正在开发 32 位系统。 Perl/Python 中的哈希算法是否也使用 32 位哈希?还是我必须跳到64?

    关于在常用脚本语言中实现哈希表:实现是否会检查冲突,或者我可以完全避免这部分吗?

【问题讨论】:

你考虑过使用 GLib 吗? developer.gnome.org/glib/2.46/glib-Hash-Tables.html 以下页面有几个用 C(和许多其他语言)实现的通用哈希函数的实现:partow.net/programming/hashfunctions/index.html 【参考方案1】:

    Here 很好地概述了最著名的散列函数。

    32 位应该可以正常工作。

    你总是需要检查冲突,除非你想写一个有趣的哈希表:)

【讨论】:

如果你不特别关心你得到的答案,你不需要检查冲突。好处是不用把原始key存储在hash表中,可以节省很多空间。 嗯,这种不确定的行为就是我所说的“有趣”。【参考方案2】:

xxhash 是一个非常快速和简单的选择。一个简单的代码将使用XXH32 函数:

unsigned int XXH32 (const void* input, int len, unsigned int seed);

它是 32 位哈希。由于lenint,对于超过2^31-1 字节的更大数据,请使用这些:

void*         XXH32_init   (unsigned int seed);
XXH_errorcode XXH32_update (void* state, const void* input, int len);
unsigned int  XXH32_digest (void* state);

【讨论】:

【参考方案3】:

hash table lookup 的通用哈希函数。它指定请勿用于加密目的,但既然您指定您没有这样做的意图,那么您应该没问题。

其中包括散列函数调查供试用

【讨论】:

【参考方案4】:

如果您使用的是类似 posix 的系统并坚持使用纯 C,我会简单地使用系统已经提供的功能。 man 3 hcreate 为您提供所有详细信息,或者您可以在此处找到在线版本 http://linux.die.net/man/3/hcreate

【讨论】:

【参考方案5】:

尝试Adler32 处理长字符串 或 Murmur2 用于短字符串。

【讨论】:

Adler32 根本不是一个很好的哈希。事实上,它甚至比 CRC-32 更糟糕,作为一个哈希。另一方面,Murmur2 是一个非常快速的散列,具有出色的分布和最坏情况的行为,因此没有理由将其限制为短字符串。我真的不明白你的建议的依据。【参考方案6】:

你可以在http://www.azillionmonkeys.com/qed/hash.html找到一个好的(和快速的)散列函数和一个有趣的读物

您唯一不应该检查冲突的情况是,如果您使用完美的散列 - 一个很好的老式查找表,例如 gperf。

【讨论】:

我建议查看 Hsieh 的分析遗漏的一个:MurmurHash2。 en.wikipedia.org/wiki/MurmurHash

以上是关于C 的最小散列函数?的主要内容,如果未能解决你的问题,请参考以下文章

散列函数的问题 - C

如何用 C 编写散列函数?

信息安全C散列函数的应用及其安全性2016011992

信息安全作业5 散列函数的应用及其安全性发展

C散列函数采用2个数字

如何将64位哈希值缩短到48位值?