Hash 低熵字母数字字符串的高效哈希函数

Hash 低熵字母数字字符串的高效哈希函数,hash,alphanumeric,Hash,Alphanumeric,我正在尝试编写一个(完美的)哈希表,用于压缩映射(从第二列映射到第一列)。如您所见,可能的输入非常有限,事实上字母表中正好有38个字符:AB…YZ,0…9,-和空格。此外,还有大量(子字符串)重复,数字零,数字一,…,拉丁大写字母a,拉丁大写字母B等 通过选择一个种子S,然后尝试通过S构建一个完美的哈希表种子(以某种方式)来计算哈希表。如果无法创建表,它将使用新种子重试。有很多冲突通常需要更多的重试,因为算法很难使所有内容都适合 结果是我的输入域的熵很低,创建表需要使用简单的散列函数(如DJB2

我正在尝试编写一个(完美的)哈希表,用于压缩映射(从第二列映射到第一列)。如您所见,可能的输入非常有限,事实上字母表中正好有38个字符:
AB…YZ
0…9
-
和空格。此外,还有大量(子字符串)重复,
数字零
数字一
,…,
拉丁大写字母a
拉丁大写字母B

通过选择一个种子
S
,然后尝试通过
S
构建一个完美的哈希表种子(以某种方式)来计算哈希表。如果无法创建表,它将使用新种子重试。有很多冲突通常需要更多的重试,因为算法很难使所有内容都适合

结果是我的输入域的熵很低,创建表需要使用简单的散列函数(如DJB2)进行多次重试;像FNV这样更好的散列器工作得还可以,但是像SipHash这样更复杂、更慢的函数平均需要更少的重试次数

由于这完全是静态的,并且是预计算的,因此为了质量,我不太担心质量(即,运行时任意输入的安全性和概率分布无关紧要),但相反,更高质量的函数减少了给定压缩级别所需的预计算时间,允许我在固定时间内实现更高的压缩

问题:是否有高效的已发布哈希函数调整为具有如下域约束的输入?也就是说,是否存在利用额外结构进行较少操作但仍能获得合理输出的哈希函数

我搜索过“字母数字哈希函数”之类的东西,但结果是不相关的(主要是生成一个字母数字字符串作为哈希函数的输出);即使是一些关于正确术语的指导,以便我可以搜索论文,也会有所帮助

(这个问题的动机是解决起来稍微有点意思,实际上没有必要。)

我正在尝试写一个(完美的)哈希表

如果你想要一个完美的散列函数,我会用类似CMPH的东西来生成它。这可能最终成为一些幕后的静态查找表

或者,您可以使用非基于散列的方法,例如使用DAWG或一些类似Trie的结构(以及顶部的一些Aho-Corasick?)

DAWG可以提供相当紧凑的存储空间,并可以快速搜索字符串到数字。 我的直觉是,它可能会击败你的问题哈希表


看一些介绍。有几种语言的实现。

您想要一个用于27268项的完美哈希吗?对我来说似乎很难。为什么不使用标准的hashfunction来处理冲突呢?(可能使用较低的填充因子)@wildplasser它工作得很好,只需要一点时间就可以生成。例如,是哈希表本身:使用输入字符串的哈希作为该表的索引(然后验证其正确性)。这个问题的重点是通过尽可能少的工作,利用输入的结构来加快速度。另外,这是为了压缩,所以低负载系数是不好的。@wildplasser最后,请注意,我目前使用的是一个标准哈希函数(我在问题中实际上提到了三个)。输入字母表的较低基数(~5.5位)其实并不重要,只要哈希函数中有足够的雪崩效应。(不变)两个前导零不应混淆“标准”哈希函数。我刚刚检查了一下,我自己的shift&xor hashfunction在38字符的字母表上的效果与在完整的~7位ascii集合上的效果一样好。问:您是在优化空间还是速度(溢出链每个条目只需要一个指针+一位)?@wildplasser优化空间,但这是通过优化速度来实现的。这里的瓶颈是生成表,它包括为哈希随机选择一个种子并尝试构建一个有效的哈希表。对于高压缩系数,可能需要尝试许多种子,因为它们通常不起作用,这可能需要很长时间。如果一个哈希函数可以通过利用输入的结构来提高效率,我将能够在更短的时间内对表进行更多的压缩。(这个问题大部分是出于兴趣,因为我总是可以把CPU时间扔给它。)