如何计算下一个ipv6地址?
How to calculate the next ipv6 address?
我被困在一个希望很简单的任务上:我想获得下一个 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() 和 fiddle 中的字符串与十六进制值分开,但必须有一个简单的解决方案来将 1 添加到 in6_addr!
除了少数例外,IPv6 地址分为两个 64 位部分:Network/Subnet 和接口 ID。您应该对接口 ID 的 64 位感兴趣。
最简单的方法是将地址解析为两个 64 位无符号整数,增加接口 ID,然后将这两部分重新组合成一个 128 位地址。
我选择了十六进制并实现了这个功能:
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 使用相同的方法。
我被困在一个希望很简单的任务上:我想获得下一个 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() 和 fiddle 中的字符串与十六进制值分开,但必须有一个简单的解决方案来将 1 添加到 in6_addr!
除了少数例外,IPv6 地址分为两个 64 位部分:Network/Subnet 和接口 ID。您应该对接口 ID 的 64 位感兴趣。
最简单的方法是将地址解析为两个 64 位无符号整数,增加接口 ID,然后将这两部分重新组合成一个 128 位地址。
我选择了十六进制并实现了这个功能:
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 使用相同的方法。