我发现了一些函数示例,这些函数可以快速散列5个turple,以在tcp连接表中识别两个方向上的流以进行tcp流重组(sha / md5太慢了。)
例如
((size_t)(key.src.s_addr) * 59) ^
((size_t)(key.dst.s_addr)) ^
((size_t)(key.sport) << 16) ^
((size_t)(key.dport)) ^
((size_t)(key.proto));
或者这是一个其中K是哈希表大小为n的键,并使用异或运算符,其中XOR操作可以表示为
H(X) = k1⊕k2⊕...kn
还是以下97位(32 + 32 + 16 + 16 + 1)的ips / ports / proto可以提供足够的随机性而不会发生冲突
src ip 80.229.161.151 = 1357226391
dst ip 80.229.161.159 = 1357226399
src port 35555
dst port 80
tcp 6
H(X) = 1357226391 * 97 ⊕ 1357226399 * 97 ⊕ 35555 * 97 ⊕ 80 * 97 ⊕ 6 * 97
hash key = 131654394123 ???
请问有人可以解释我是否正确吗?
还是让我指向一些很好的论文来解释如何做到这一点?
答案 0 :(得分:0)
最重要的是:取决于。如果流量中的源IP和目标IP分布合理,并且端口分布合理,则对于哈希表而言,其中任何一个都可能很好。但是,如果您碰巧正在查看的网络流量中,一组很小的IP地址之间有很多连接,或者只有很少的不同端口,那么事情就会变得更加棘手。
通常,对于哈希表,哈希的结果不需要是完美的。不是您需要完全消除冲突,只是不希望它们频繁发生,或者不是导致许多条目共享一小组哈希桶,而许多其他哈希桶都未使用。但这很大程度上取决于您的应用程序以及网络流量的来源。在最坏的情况下,最好还是尽量减少对输入和设计的依赖。
经常采用的一种将此类冲突减至最少的方法是找到一种快速,有效,非加密的通用哈希,然后将元组中的所有地址和端口放在一个连续的缓冲区中,然后在缓冲并将结果折叠到哈希表索引中。
在下面的第一个链接中是此定义:
非加密哈希函数将字符串作为输入并计算整数输出。哈希函数的理想属性是输出在可能的输出域中均匀分布,尤其是对于相似的输入。与加密散列函数不同,这些函数的设计目的不是承受攻击者寻找冲突的努力。
(为弄清最后一句话,这些哈希函数 do 最大限度地减少了冲突;只是没有做出任何努力使它们对可能导致构造冲突的密码分析产生抵抗力 >。)
看看这些页面,其中包含有关“最近”开发的大量信息:
通常,这些散列比临时XOR实现要慢,但比SHA和MD5等加密散列要快得多。当然,哈希函数的速度取决于您的判断-但以我的经验,获取TCP / IP 5元组的哈希值用作哈希表的索引很少会成为问题。明显的性能瓶颈。通常,处理的其他部分在性能方面会更加昂贵-尤其是如果您要进行TCP流重组时,这将需要大量的缓冲区和内存管理,数据复制等。
使用通用哈希函数的另一个优点:当您准备添加IPv6支持时,不需要任何新算法。您只需布置更大的缓冲区,将16字节的IPv6地址复制到其中,然后运行相同的哈希函数即可。
另请参阅软件工程SE中的相关问题,该问题的优点是可以在SO上“现场”进行: https://softwareengineering.stackexchange.com/q/49550/261672