c-如何从IP数据包的不同字段中计算哈希值



我需要实现一个哈希表来维护IP数据包。然而,由于数据包的唯一性,我无法使用单个元素(比如IP地址)创建哈希密钥。以下是包中负责使包唯一的元素:

  1. 源IP地址(由于IPv6格式,为16字节字符串)
  2. 源端口(2字节)
  3. 目标ip地址(再次为16字节)
  4. 目标端口(2字节)5。id1(1字节)

我知道,如果有一个元素可以计算哈希值,那么它可以使用任何已知的算法(如MD5等)来完成。我的问题是,在计算哈希值的过程中,我如何包括如上所述的多个元素?

您提到您知道如何对单个元素进行散列。

然后,您可以将所有列出的元素放在一个缓冲区中(比如大小为16+2+16+2+1的无符号char数组),然后将该缓冲区视为一个元素。

创建有效的哈希;首先确定要用于查找的数据。例如,如果你要搜索从某个IP地址发送的所有数据包,那么你只想使用"源IP地址"(你不想使用源IP地址和源端口,因为这意味着你必须进行65536次搜索才能找到从某个IP地址发送的全部数据包)。

下一步是确定最有效的哈希大小。这往往取决于数据量和CPU缓存的大小。如果哈希大小太小(例如8位),那么每个哈希的条目列表都很长(这会增加查找任何内容的时间);如果散列大小太大(例如24位),那么在试图查找散列的条目列表时,会经常发生缓存未命中。

请注意,您也可以有多个级别。例如,如果您想搜索来自特定端口和IP地址的数据包;那么您可以单独使用IP地址来创建一个哈希表,该哈希表用于查找第二个哈希表;然后使用该端口来创建与第二哈希表一起使用的不同哈希。

一旦您决定了哈希和哈希大小需要使用什么信息;下一步是确定如何以最小化冲突的方式计算哈希。这种计算需要快速——你不希望有大量的开销来阻止少量的开销(使用像MD5这样复杂的东西是个坏主意)。通常,像"XOR和移位"这样的简单方法既快速又有效。例如,对于一个16字节的IP地址和16位的散列,您可能只需要执行hash ^= (hash << 3) | next_pair_of_bytes;8次。

最后,你想对它进行调优。大多数情况下,你想调整哈希大小,并尝试一些不同的哈希计算,看看它是否能提高性能。以上所有内容都依赖于对数据和缓存大小的假设,而这些假设在实践中可能是错误的。例如,可能大多数数据包来自单个IP地址,在散列中使用该IP地址是浪费时间;程序的其他部分可能消耗了大量缓存,试图最大限度地减少缓存未命中是个坏主意(更大的哈希可能会提高性能);也许没有你想象的那么多数据,也没有得到太多哈希冲突,减少哈希大小可以提高性能;等

最新更新