散列ip片段的散列函数

时间:2016-09-30 09:11:51

标签: c algorithm function hash

我必须将传入的ipv4片段哈希到大小为20的结构的静态数组。用于散列的字段是IP-ID(16位),协议(8位),源IP地址(32位)和目标IP地址(32位)。散列应该很快并且在C中实现起来不是很复杂。在这种情况下,什么是好的散列函数?

3 个答案:

答案 0 :(得分:0)

如果我理解正确并且您只想要20个哈希值,则可以直接对数据使用模运算符(%)。

如果您的数据分发是有利的,并且您将它们存储为整数,则可能会使用hash = ip_fragment % 20

似乎很多碰撞都会发生,所以你可以保持简单。

答案 1 :(得分:0)

如果您可以假设所有参数都是不相关的并且均匀分布,那么您可以将您感兴趣的字段的所有字节排在一起,最后取模20的结果。但是,如果您有双向流,则意味着两个方向都被散列到相同的值(因为在这个简单的算法中交换字段无关紧要)。 你应该看看像MurmurHash这样的快速通用哈希算法。

但是,如果哈希表中只有20个条目,则很可能会发生冲突。如果接收到的数据包之间存在强烈的时间关联,例如,您很可能会连续收到许多具有相同标头的数据包,那么您可能最好只拥有一个(或几个)仅记录的缓存条目最后(唯一)接收到的头,然后立即将下一个数据包与那些缓存条目进行比较,而不进行任何哈希。

不要忘记测量您正在使用的散列或缓存方法的实际性能。

答案 2 :(得分:0)

%20实际上是次优的。像这样的简单哈希:

% 20

是5 amd64指令(shift,mov,xor,xor或xor)。但是添加uint32_t ip_fragment_hash(uint16_t ip_id, uint8_t ip_proto, uint32_t ip_src, uint32_t ip_dst) { uint32_t h = (ip_id << 16 | ip_proto) ^ ip_src ^ ip_dst; h = h ^ (h >> 5) ^ (h >> 10) ^ (h >> 15) ^ (h >> 20) ^ (h >> 25) ^ (h >> 30); return h % 32; } 并获得14条指令,包括一次扩展乘法。将其设为32并将其折叠起来:

{{1}}