我有来自Microsoft Azure数据中心(http://www.microsoft.com/en-us/download/confirmation.aspx?id=41653)的900多个IP地址范围,我想知道IP地址是否来自其中一个地址。我已将其转换为单个列表,可以存储在文本文件中。
所以:循环遍历每个地址并使用ip2long()(例如此处的第3点)(https://mebsd.com/coding-snipits/php-ipcalc-coding-subnets-ip-addresses.html)是否成本更高或者更好地转换范围内的所有IP地址,将它们存储在数据库中那么看看他们?如果是后者,如何实现这一点(即将范围转换为其中的所有IP地址)?
对我而言,关键在于它必须很快,因为我们会经常检查这一点。
示例IP地址/范围:
40.112.124.0/24
65.52.128.0/19
94.245.97.0/24
104.47.169.0/24
104.214.240.0/24
137.116.192.0/19
157.55.8.96/27
157.55.8.128/27
157.55.8.160/28
168.63.0.0/19
答案 0 :(得分:5)
创建一个包含列" range_start"的表和" range_end"和这些列上的索引。对于每个IP地址范围,插入一行,其中包含范围的开头和结尾。完成后,您的行数少于1000行。现在,测试IP地址......
SELECT * FROM IP_RANGES WHERE $testIP>=range_start AND $testIP<=range_end
(修改此SQL语句以匹配您调用数据库的方式,最好使用PDO,最好采用SQL注入安全方式)。
更新:抱歉,在我输入答案时错过了上述评论。
@ Ukuser32,是的,使用ip2long
将点分十进制转换为长整数(更容易使用;在数据库中存储长整数)。要获得范围的结束,请查看CIDR的第2部分。从左侧开始的位数(N)固定在该范围内。这意味着32-N是可变位的数量。这意味着该范围内有2 **(32-N)ips。这意味着可以计算$ range_end ......
list($range_start, $range_end) = cidr2range('40.112.124.0/24');
echo "Start: $range_start, end: $range_end\n";
function cidr2range($cidr) {
$cidr = explode('/', $cidr);
$range_start = ip2long($cidr[0]);
$range_end = $range_start + pow(2, 32-intval($cidr[1])) - 1;
return [$range_start, $range_end];
}