1

我有一个起始 IPv4 IP 地址5.39.28.128(或::ffff:5.39.28.128)并且我有 IPv6 网络掩码长度122,我如何计算该范围内的最后一个 IP?

我相信我需要将起始 IP 转换为二进制,如下所示,我不知道从那里去哪里得到最终 IP。

$ipNumber = ip2long('5.39.28.128');
$ipBinary = decbin($ipNumber);

echo $ipBinary; // 101001001110001110010000000

原因是我将 CSV 格式的 MaxMind GeoIP 数据库导入 MySQL 数据库(因此如果需要可以使用 MySQL 函数)。MaxMind 不再提供结束 IP,而是提供起始 IP 和 IPv6 网络掩码长度。

4

2 回答 2

4

给你。我已将此响应中inet_to_bits的函数复制到另一个问题。

<?php

function inet_to_bits($inet) {
   $inet = inet_pton($inet);
   $unpacked = unpack('A16', $inet);
   $unpacked = str_split($unpacked[1]);
   $binaryip = '';
   foreach ($unpacked as $char) {
             $binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
   }
   return $binaryip;
}

function bits_to_inet($bits) {
    $inet = "";
    for($pos=0; $pos<128; $pos+=8) {
        $inet .= chr(bindec(substr($bits, $pos, 8)));
    }
    return inet_ntop($inet);
}

$ip = "::ffff:5.39.28.128";
$netmask = 122;

// Convert ip to binary representation
$bin = inet_to_bits($ip);

// Generate network address: Length of netmask bits from $bin, padded to the right
// with 0s for network address and 1s for broadcast
$network = str_pad(substr($bin, 0, $netmask), 128, '1', STR_PAD_RIGHT);

// Convert back to ip
print bits_to_inet($network);

输出:

::ffff:5.39.28.191
于 2014-06-02T10:44:52.500 回答
2

解决方案很简单:

// Your input data
$networkstart = '5.39.28.128';
$networkmask = 122;

// First find the length of the block: IPv6 uses 128 bits for the mask
$networksize = pow(2, 128 - $networkmask);

// Reduce network size by one as we really need last IP address in the range,
// not first one of subsequent range
$networklastip = long2ip(ip2long($networkstart) + $networksize - 1);

$networklastip 将具有该范围内的最后一个 IP 地址。

现在,这仅适用于 IPv6 地址空间中的 IPv4 地址。否则,您需要使用 IPv6 到/从 128 位整数函数而不是 ip2long/long2ip。但是,上面的 MaxMind 数据代码使用就足够了,因为我还没有看到任何来自它们的实际 IPv6 数据。

于 2014-06-06T10:11:06.577 回答