简体   繁体   English

如何根据起始IP和网络掩码长度计算范围内的最终IP

[英]How to calculate end IP in the range, based on start IP and network mask length

I have a starting IPv4 IP address 5.39.28.128 (or ::ffff:5.39.28.128 ) and I have the IPv6 network mask length 122 , how can I calculate the last IP in the range? 我有一个起始IPv4 IP地址5.39.28.128 (或::ffff:5.39.28.128 ),并且具有IPv6网络掩码长度122 ,如何计算该范围内的最后一个IP?

I believe I need to convert the start IP to binary, which I'm doing like below, I don't know where to go from there to get the end IP. 我相信我需要将起始IP转换为二进制,这与下面的操作类似,我不知道从那里获取最终IP。

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

echo $ipBinary; // 101001001110001110010000000

The reason is I'm importing the MaxMind GeoIP database in CSV format into a MySQL database (so MySQL functions can be used if needed). 原因是我将CSV格式的MaxMind GeoIP数据库导入到MySQL数据库中(因此,如果需要,可以使用MySQL函数)。 MaxMind no longer provide the end IP, in favour of providing the start IP and the IPv6 network mask length instead. MaxMind不再提供最终IP,而是改为提供起始IP和IPv6网络掩码长度。

Here you are. 这个给你。 I've copied the inet_to_bits function from this response to another question . 我已将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);

Output: 输出:

::ffff:5.39.28.191

Solution is quite simple: 解决方法很简单:

// 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 will have last IP address in the range. $ networklastip将具有该范围内的最后一个IP地址。

Now this is good solution ONLY for IPv4 addresses in IPv6 address space. 现在,仅对于IPv6地址空间中的IPv4地址,这是一个很好的解决方案。 Otherwise you need to use IPv6 to/from 128 bit integer functions instead of ip2long/long2ip. 否则,您需要对128位整数函数使用IPv6或从中使用IPv6代替ip2long / long2ip。 However for use by MaxMind data code above is sufficient as I have not seen any actual IPv6 data from them yet. 但是,对于上面的MaxMind数据代码来说,使用它们已经足够了,因为我还没有看到它们中的任何实际IPv6数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM