PHP5从cidr前缀计算IPv6范围? [英] PHP5 calculate IPv6 range from cidr prefix?
问题描述
我可以使用来自各种在线资源的代码片段对IPv4进行此操作.我想知道是否可以使用IPv6做到这一点.
I am able to do this with IPv4 using code snippets from various online sources. I was wondering if there was a way to do it with IPv6.
基本上,我只需要一个可以输入IPv6地址和前缀(例如:address/68)的表格,它就可以计算网络地址,第一个可用地址,最后一个可用地址和广播地址.然后只打印到屏幕上.不想将其存储在数据库中或其他任何内容中.
Basically I just need a form that I can enter an IPv6 address and prefix (ex: address/68) and it calculates the network address, first useable address, last useable address, and broadcast address. Then just prints to screen. Not looking to store it in a database or anything yet.
我将如何去做?
提前感谢大家!
推荐答案
首先:IPv6没有网络和广播地址.您可以在前缀中使用所有地址.第二:在LAN上,前缀长度始终为(/99.x%的时间)/64.路由/68将破坏IPv6功能,例如无状态自动配置.
First of all: IPv6 doesn't have network and broadcast addresses. You can use all addresses in a prefix. Second: On a LAN the prefix length is always (well, 99.x% of the time) a /64. Routing a /68 would break IPv6 features like stateless auto configuration.
以下是IPv6前缀计算器的详细实现:
Below is a verbose implementation of an IPv6 prefix calculator:
<?php
/*
* This is definitely not the fastest way to do it!
*/
// An example prefix
$prefix = '2001:db8:abc:1400::/54';
// Split in address and prefix length
list($firstaddrstr, $prefixlen) = explode('/', $prefix);
// Parse the address into a binary string
$firstaddrbin = inet_pton($firstaddrstr);
// Convert the binary string to a string with hexadecimal characters
# unpack() can be replaced with bin2hex()
# unpack() is used for symmetry with pack() below
$firstaddrhex = reset(unpack('H*', $firstaddrbin));
// Overwriting first address string to make sure notation is optimal
$firstaddrstr = inet_ntop($firstaddrbin);
// Calculate the number of 'flexible' bits
$flexbits = 128 - $prefixlen;
// Build the hexadecimal string of the last address
$lastaddrhex = $firstaddrhex;
// We start at the end of the string (which is always 32 characters long)
$pos = 31;
while ($flexbits > 0) {
// Get the character at this position
$orig = substr($lastaddrhex, $pos, 1);
// Convert it to an integer
$origval = hexdec($orig);
// OR it with (2^flexbits)-1, with flexbits limited to 4 at a time
$newval = $origval | (pow(2, min(4, $flexbits)) - 1);
// Convert it back to a hexadecimal character
$new = dechex($newval);
// And put that character back in the string
$lastaddrhex = substr_replace($lastaddrhex, $new, $pos, 1);
// We processed one nibble, move to previous position
$flexbits -= 4;
$pos -= 1;
}
// Convert the hexadecimal string to a binary string
# Using pack() here
# Newer PHP version can use hex2bin()
$lastaddrbin = pack('H*', $lastaddrhex);
// And create an IPv6 address from the binary string
$lastaddrstr = inet_ntop($lastaddrbin);
// Report to user
echo "Prefix: $prefix\n";
echo "First: $firstaddrstr\n";
echo "Last: $lastaddrstr\n";
?>
它应该输出:
Prefix: 2001:db8:abc:1400::/54
First: 2001:db8:abc:1400::
Last: 2001:db8:abc:17ff:ffff:ffff:ffff:ffff
这篇关于PHP5从cidr前缀计算IPv6范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!