我想创建一个32位的哈希值。我有16字节的源和目标ipv6地址以及2字节的源端口号和目标端口号。
32位输出=(Src IP、Dst IP、Src端口、Dest端口)
如果散列函数沿着32位空间很好地分布实体,则会更好。我想用结果作为索引。
调整
另一个可能有用的参考:
通用散列函数算法
谷歌的CityHash
请注意,很难创建一个无冲突保证的哈希函数(在同一个哈希代码中没有不同的输入结果)。这个问题有很多解决方案,最简单的是开放寻址。
打开寻址
32位用于索引?你的桌子有多大?!
考虑一下,大多数IPv6地址将基于硬件地址。看看RFC 4291:
[EUI64] defines a method to create an IEEE EUI-64 identifier from an
IEEE 48-bit MAC identifier. This is to insert two octets, with
hexadecimal values of 0xFF and 0xFE (see the Note at the end of
appendix), in the middle of the 48-bit MAC (between the company_id
and vendor-supplied id). An example is the 48-bit IEEE MAC with
Global scope:
|0 1|1 3|3 4|
|0 5|6 1|2 7|
+----------------+----------------+----------------+
|cccccc0gcccccccc|ccccccccmmmmmmmm|mmmmmmmmmmmmmmmm|
+----------------+----------------+----------------+
在这种情况下,尝试这种在大多数情况下都有效的快速而肮脏的黑客攻击(假设端口和MAC地址分布均匀):
- 取源IPv6地址的低16位。将其向左移动16位,并与目标IP地址的低16字节进行"或"运算
- 取源端口。将其向左移动16位,然后与目标端口进行"或"运算
- 将上面两个32位值的结果异或在一起
如果用户使用手动分配的地址,这个散列函数的分布不会很均匀,但我认为在大多数情况下它会很接近。如果需要,您可以从地址的上半部分插入(XOR)一些位。
请参阅Eternally Confuzzled,了解有关哈希函数和一些著名算法的一些一般信息;我可能会选择FNV或詹金斯的一次性哈希。
murmurhash速度非常快,而且相当受人尊敬。这不是加密强度,但它应该足以满足您的目的。