如何比较IP地址?

13

我需要在我的服务器应用中检查一个IP地址是否在黑名单中。

比较IP地址的最有效方式是什么?将IP地址转换为整数并进行比较会更高效吗?


1
你的黑名单是一个文件、加载在内存中、在数据库中,还是其他什么形式? - Forgotten Semicolon
1
不管黑名单位于何处,它仍将由CPU进行比较。但是如果您认为我应该在我的问题中提到这一点,请告诉我为什么黑名单的位置很重要。 - MrValdez
1
@MrValdez:从磁盘获取黑名单的时间远远超过将其所有条目从int转换为string或反之亦然的时间。 - MSalters
12个回答

30

取决于你使用的编程语言,但通常在网络层,IP地址被存储为32位无符号整数,这样比较非常快。即使不是这样,除非你正在设计高性能的数据包交换应用程序,否则不太可能成为性能瓶颈。避免过早优化——为可测试性和可扩展性设计程序,如果出现性能问题,则可以使用分析器查看瓶颈所在位置。

编辑:澄清一下,IPv4地址被存储为32位整数,加上网络掩码(对于IP地址比较并不必要)。如果你正在使用更新且目前更为罕见的IPv6,则地址将为128位长。


或许需要更新,9.5年后现在更为罕见。 - MichaelChirico

7

32位整数是首选——直到你开始处理128位的IPv6地址。


7

你的意思是将其作为文本字符串进行比较还是将int转换为int并作为int进行比较?

通常这种查找中这不是瓶颈。你可以尝试实现两种方法,看哪一种运行更快。

IP地址查找的真正问题通常是进行有效查询,利用您正在处理的IP地址而不仅仅是随机数字的事实。为了实现这一点,您可以查找LC trie

显然,只有当黑名单拥有数万或数百万条目时,这才会引起您的兴趣。如果它只有10-20个条目,则应优先选择线性搜索,实际上更有趣的问题是文本比较与整数比较。


4

我发现这是有效的,但会比较冗长,当然你需要将黑名单IP以整数形式索引。


3

使用像PeerGuardian这样的工具,在驱动程序级别禁止黑名单上的IP地址进行传入TCP/IP连接。高度安全,无需编写代码(可以说:高度安全,因为不需要编写代码)。


3
我已经完成了这个任务并进行了测试,使用无符号整型(32位)是最快的——我假设你正在将其与字符串表示进行比较。
另一件可能对你有帮助的事情是,在创建表格时,过去我有两列:LowIP和HighIP;这样我就能够用一个记录条目黑名单整个IP范围,并通过检查范围内的IP来获得良好的性能。

3
我曾经接手过一段代码,其中有人认为将IP地址存储为4个整数是一件非常好的事情,但是他们花费了大量时间进行转换。将它们作为字符串存储在数据库中要容易得多,而且只需要一个索引。你会惊讶地发现,与4列整数相比,SQL Server可以很好地对字符串进行索引。但是这个IP列表不是用于黑名单。数据库往返成本非常高。
如果数据库过于复杂,请将它们存储在内存中的字典中,但这只是一个猜测,因为我们不知道您需要比较多少个IP地址。由于大多数哈希码是32位整数,并且IPv4地址也是32位的,因此IP地址本身可能是一个很好的哈希码。
但正如其他人指出的那样,最好的选择可能是减轻服务器负载并购买专门的硬件。也许您可以将最近被列入黑名单的IP地址保留在内存中,并定期将新的IP地址发布到路由器上。
如果您是尝试在路由器内部创建一些软件的人,则需要找出您的数据结构书,并创建类似于B树的东西。

1
比较一个糟糕的表示(4个整数)与另一个(字符串),实际上并不公平。 - MSalters
1
这是对KISS原则的一个轶事回应,将IP地址存储为字符串对于手头的目的已经足够。 - Robert Paulson

3

flow-tools网站非常好!那里有许多好的链接,例如这个:http://www.splintered.net/sw/flow-tools/SECURITY。谢谢! - Ellie Kesselman
这个 flow-tools 的链接无法使用。 - Elango Mani

2

您是否存在效率方面的问题?

如果是这样,请发布代码(或伪代码),我们可以对其进行分析。

如果没有,我建议尝试一些简单的方法,例如将条目存储在排序列表中,并使用您环境中现有的 Sort()Find()


2

整数比较比字符串比较要快得多。

如果你把整数存储在一个有序列表中,你可以比在无序列表中更快地找到它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接