如何计算下一个ipv6地址?

时间:2015-10-13 13:36:32

标签: php binary ipv6

我被困在一个有希望的简单任务上:我想获得下一个IP地址。

以下是我的一些测试:

    //$binaryIp = inet_pton('192.168.1.1');
    $binaryIp = inet_pton('2001:cdba::1');

    $verySimple = inet_ntop(
        $binaryIp++
    );
    var_dump($verySimple); //'2001:cdba::1'

    $simpleMaths = inet_ntop(
        $binaryIp + inet_pton('0.0.0.1')
    );
    var_dump($simpleMaths); //inet_ntop(): Invalid in_addr value

    $aLittleBitOfSuccess = long2ip(
        ip2long(inet_ntop($binaryIp)) + 1
    );
    var_dump($aLittleBitOfSuccess); //'0.0.0.1' but with IPv4 '192.168.1.2'

好的,直到这里显而易见的是,我的尝试比我的问题更真实,但我还能尝试什么呢?我已经在网上搜索过并找到了一些子网计算的解决方案和类似的东西,但没有简单的加法或减法。

我的下一个尝试是将字符串从inet_ntop()中拆分并使用十六进制值进行调整但是必须有一个简单的解决方案来向in6_addr添加1!

2 个答案:

答案 0 :(得分:0)

除少数例外情况外,IPv6地址分为两个64位部分:网络/子网和接口ID。您应该对接口ID的64位感兴趣。

最简单的方法是将地址解析为两个64位无符号整数,递增接口ID,然后将这两个部分重新组合成128位地址。

答案 1 :(得分:0)

我选择了十六进制并完成了这个功能:

protected function binaryIncrement($binaryIp, $increment = 1) {

    //inet_pton creates values where each "character" is one ip-address-byte
    //we are splitting the string so we can handle every byte for itselve.
    $binaryIpArrayIn = str_split($binaryIp);
    $binaryIpArrayOut = array();
    $carry = 0 + $increment;
    //reverse array because our following addition is done from right to left.
    foreach (array_reverse($binaryIpArrayIn) as $binaryByte) {
        //transforming on byte from our ip address to decimal
        $decIp = hexdec(bin2hex($binaryByte));
        $tempValue = $decIp + $carry;
        $tempValueHex = dechex($tempValue);
        //check if we have to deal with a carry
        if (strlen($tempValueHex) > 2) {
            //split $tempValueHex in carry and result
            //str_pad because hex2bin only accepts even character counts
            $carryHex = str_pad(substr($tempValueHex,0,1),2,'0',STR_PAD_LEFT);
            $tempResultHex = str_pad(substr($tempValueHex,1,2),2,'0',STR_PAD_LEFT);
            $carry = hexdec($carryHex);
        } else {
            $carry = 0;
            $tempResultHex = str_pad($tempValueHex,2,'0',STR_PAD_LEFT);
        }
        //fill our result array
        $binaryIpArrayOut[] = hex2bin($tempResultHex);
    }
    //we have to reverse our arry back to normal order and building a string
    $binaryIpOut = implode(array_reverse($binaryIpArrayOut));

    return $binaryIpOut;
}

$binaryIpV6In = inet_pton('2001:cdba::FFFF');
$binaryIpV6Out = $this->binaryIncrement($binaryIpV6In);
var_dump(inet_ntop($binaryIpV6Out));
$binaryIpV4In = inet_pton('192.168.1.1');
$binaryIpV4Out = $this->binaryIncrement($binaryIpV4In, 256);
var_dump(inet_ntop($binaryIpV4Out));

这样我可以对IPv4和IPv6使用相同的方法。