我有~12600个子网:
例如:123.123.208.0/20
一个IP。
我可以使用SQLite数据库或数组等
大约一个月前有一个类似的问题,但我不是在寻找检查一个IP对一个子网,而是一堆子网(显然是最有效的方式,希望不是O(总子网)):)
我如何检查IP是在这些子网之一,我需要真或假,而不是子网,如果这有助于优化。
当前列表中有类似的子网,例如:(实际浸提液)
123.123.48.0/22 <-- not a typo
123.123.48.0/24 <-- not a typo
123.123.90.0/24
123.123.91.0/24
123.123.217.0/24
它们的总范围为4.x.y.z至222.x.y.z
6条答案
按热度按时间xj3cbfub1#
最好的方法是使用位运算符的IMO。例如,
123.123.48.0/22
表示(123<<24)+(123<<16)+(48<<8)+0
(=2071670784;这可能是一个负数)作为一个32位数字IP地址,-1<<(32-22)
= -1024作为一个掩码。用这个,同样,你的测试IP地址转换为一个数字,你可以做:例如,123.123.49.123就在该范围内,因为
2071671163 & -1024
是2071670784下面是一些工具函数:
测试:
得到
true
。如果您的掩码格式为'255.255.252.0',则您也可以使用掩码的IPnumber函数。
fd3cxomn2#
试试这个:
使用方法:
pgpifvop3#
我通过使用node netmask模块成功解决了这个问题。您可以通过如下方式检查IP是否属于子网:
将在这里打印
true
。您可以使用以下命令安装它:
ct2axkht4#
将范围中的低ip和高ip转换为整数,并将范围存储在数据库中,然后确保两列都被索引。
Off the top of my head(伪代码):
应该可以了
要查找特定ip是否福尔斯任何范围,请将其转换为整数并执行以下操作:
查询优化器应该能够大大加快这一过程。
j1dl9f465#
函数
IPnumber
和IPmask
很好,但是我更愿意像这样测试:因为对于每个地址,您只需要考虑地址的网络部分。因此执行
IPmask('22')
将清零地址的计算机部分,您应该对网络地址执行相同的操作。icnyk63a6#
关键词:二分查找、预处理、排序
我也遇到过类似的问题,如果你能对子网列表进行预处理并排序,那么二分查找似乎非常有效。然后你可以实现**O(log n)**的渐近时间复杂度。
下面是我的代码(MIT许可证,原始位置:https://github.com/iBug/pac/blob/854289a674578d096f60241804f5893a3fa17523/code.js):
以及示例用法:
你可以get a PAC script*,看看它是如何执行的(它从其他地方加载中国IP列表,对它们进行排序并适当地格式化)对5000个子网。在实践中,它的速度令人惊讶地令人满意。
预处理代码可以使用上面页面上的F12 Dev Tools进行检查。简而言之,您需要将
1.2.3.4/16
转换为[0x01020304, 0xFFFF0000]
,即IP地址和网络掩码的32位无符号整数。