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 位哈希。由于len
是int
,对于超过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 的最小散列函数?的主要内容,如果未能解决你的问题,请参考以下文章