【问题标题】:What is the best way to get /24 blocks from IP address ranges?从 IP 地址范围获取 /24 块的最佳方法是什么?
【发布时间】:2021-12-10 20:40:26
【问题描述】:

我正在尝试找出使用 PHP 从一系列 IP 地址中获取单个 /24 IP 块的最佳/最有效方法。

我在 MySQL 数据库中有 IP 地址范围(我无法更改其显示方式)并且必须以特定方式保存各个范围的 /24 块(我无法更改 MySQL 条目,也无法更改软件处理列表)。

例如,我有各种不同范围的 IPv4 IP 地址,格式如下:

86.111.160.0 - 86.111.175.255

我需要以这种特定格式保存以表示给定地址范围内的每个 /24 块:

86.111.160.0
86.111.161.0
86.111.162.0
...
86.111.175.0

在不编写非常复杂的东西来处理每一行的情况下,我对如何做到这一点有点困惑。

PHP 中有什么函数可以帮助我解决这个问题吗?

提前致谢。

【问题讨论】:

标签: php


【解决方案1】:

这是https://www.php.net/manual/en/ref.network.php#74656的例子

一个简单且非常快速的检查 CIDR 的函数。

这个例子考虑了你的范围参数

在这里(仅使用算术运算符并且仅调用 ip2long () 和 split() ):

<?php


function ipCIDRCheck ($IP, $CIDR) {
    list ($net, $mask) = explode("/", $CIDR);
   
    $ip_net = ip2long ($net);
    $ip_mask = ~((1 << (32 - $mask)) - 1);

    $ip_ip = ip2long ($IP);

    $ip_ip_net = $ip_ip & $ip_mask;

    return long2ip($ip_ip_net);
  }

  $range = "86.111.160.0 - 86.111.175.255";
  list($lower,$upper) = explode('-',$range);
  $lowerIp = ip2long(trim($lower));
  $upperIp = ip2long(trim($upper));

  while($lowerIp <= $upperIp){
    echo ipCIDRCheck(long2ip($lowerIp),long2ip($lowerIp) .'/24') . "\n\r";
    $lowerIp += 255;
  }

【讨论】:

  • 这在 2021 年应该不是问题,但请注意,IPv4 地址的位操作仅在 64 位 PHP 发行版中可靠工作。
  • 谢谢,但我无法修改显示给我的范围的方式,所以我必须先将它们转换回 CIDR 格式才能使用它。
  • @omega1 我已更新代码以接受您的范围参数并返回您的掩码。将范围更改为您喜欢的范围
【解决方案2】:

你可以使用这个库:https://github.com/S1lentium/IPTools

看起来这与您所追求的相似。此库中还有许多其他方法可供您使用。

迭代网络 IP 地址:

$network = Network::parse('192.168.1.0/24');
foreach($network as $ip) {
    echo (string)$ip . '<br>';
}

// Output
192.168.1.0
...
192.168.1.255

迭代范围 IP 地址:

$range = Range::parse('192.168.1.1-192.168.1.254');
foreach($range as $ip) {
    echo (string)$ip . '<br>';
}

// Output
192.168.1.1
...
192.168.1.254

【讨论】:

  • 谢谢,我会看看那个库,但我不需要某个范围内的单个 IP 地址,我需要根据 OP 专门保存该范围内的每个 /24 块。
猜你喜欢
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2018-03-19
相关资源
最近更新 更多