php计算网段内所有IP,分配子网段
由于最近业务需要,写了个获取网段内所有IP的函数,以及分配可用子网段的函数
/**
* 根据网段获取计算所有IP
* @param string $segment 网段 '139.217.0.1/24'
* @return array IP列表 ['139.217.0.1','139.217.0.2'……]
*/
function getIpBySegment($segment)
{
$segmentInfo = explode("/", $segment);//['139.217.0.1',24]
$beginIpArray = explode(".", $segmentInfo[0]);//[139,217,0,1]
$mask = intval($segmentInfo['1']);//
$endIp = array();
foreach ($beginIpArray as $ipKey => $item) {
$beginFlag = 8 * ($ipKey);//0 8 16 24
$endFlag = 8 * ($ipKey + 1);//8 16 24 32
$decbinItem = str_pad(decbin($item), 8, "0", STR_PAD_LEFT);
$endIp[] = $mask >= $endFlag ? $item : ($mask > $beginFlag ? bindec(str_pad(substr($decbinItem, 0, $mask - $beginFlag), 8, "1", STR_PAD_RIGHT)) : ($ipKey <= 2 ? pow(2, 8) - 1 : pow(2, 8) - 1));
}
$ipArray = array();
for ($beginIp[0] = $beginIpArray[0]; $beginIp[0] <= $endIp[0]; $beginIp[0]++) {
for ($beginIp[1] = $beginIpArray[1]; $beginIp[1] <= $endIp[1]; $beginIp[1]++) {
for ($beginIp[2] = $beginIpArray[2]; $beginIp[2] <= $endIp[2]; $beginIp[2]++) {
for ($beginIp[3] = $beginIpArray[3]; $beginIp[3] <= $endIp[3]; $beginIp[3]++) {
$ipArray[] = implode(".", $beginIp);
}
}
}
}
return $ipArray;
}
/**
* 在指定网段中分配子网段
* @param string $segment 指定网段
* @param int $ipNum 需要的IP数
* @param array $usedIpArray 不可用(已经使用)的IP,默认为空数组
* @return bool|string 成功则返回分配的网段
*/
function allocateSegment($segment, $ipNum, $usedIpArray = [])
{
$usedIpArray = empty($usedIpArray) ? [] : array_flip($usedIpArray);
//计算需要多少个IP
$i = 0;
$ipCount = pow(2, $i);
while ($ipCount < $ipNum) {
$i++;
$ipCount = pow(2, $i);
}
$newMask = 32 - $i;
//大网段的开始和结束IP
$segmentInfo = explode("/", $segment);//['139.217.0.1',24]
$beginIpArray = explode(".", $segmentInfo[0]);//[139,217,0,1]
$mask = intval($segmentInfo['1']);//
if ($newMask < $mask) {
return false;
}
$endIp = array();
$step = [];
foreach ($beginIpArray as $ipKey => $item) {
$beginFlag = 8 * ($ipKey);//0 8 16 24
$endFlag = 8 * ($ipKey + 1);//8 16 24 32
$step[$ipKey] = $newMask > $endFlag ? 1 : ($endFlag - $newMask < 8 ? pow(2, $endFlag - $newMask) : pow(2, 8));
$decbinItem = str_pad(decbin($item), 8, "0", STR_PAD_LEFT);
$endIp[] = $mask >= $endFlag ? $item : ($mask > $beginFlag ? bindec(str_pad(substr($decbinItem, 0, $mask - $beginFlag), 8, "1", STR_PAD_RIGHT)) : ($ipKey <= 2 ? pow(2, 8) - 1 : pow(2, 8) - 1));
}
//遍历生成网段
for ($beginIp[0] = $beginIpArray[0]; $beginIp[0] <= $endIp[0]; $beginIp[0] += $step[0]) {
for ($beginIp[1] = $beginIpArray[1]; $beginIp[1] <= $endIp[1]; $beginIp[1] += $step[1]) {
for ($beginIp[2] = $beginIpArray[2]; $beginIp[2] <= $endIp[2]; $beginIp[2] += $step[2]) {
for ($beginIp[3] = $beginIpArray[3]; $beginIp[3] <= $endIp[3]; $beginIp[3] += $step[3]) {
$newSegment = implode('.', $beginIp) . '/' . $newMask;
//获取该网段所有的IP
$ipArray = getIpBySegment($newSegment);
$canUse = true;
//判断该网段是否可用
if (!empty($usedIpArray)) {
foreach ($ipArray as $ip) {
if (isset($usedIpArray[$ip])) {
$canUse = false;
break;
}
}
}
if ($canUse) {
return $newSegment;
}
}
}
}
}
return false;
}
php计算网段内所有IP,分配子网段的更多相关文章
- IP分配及网段划分
1.IP我们先来了解一下3类常用的IP A类IP段 0.0.0.0 到127.255.255.255 B类IP段 128.0.0.0 到191.255.255.255 C类IP段 192.0.0. ...
- Linux下同一网段内的IP中两台主机通信不经过路由器(ARP)(转)
答案一:同一网段A与B通信,不需要路由器介入. A直接广播ARP request 到广播域,B处于同一广播域,可以接收到ARP request,B用单播方式直接告诉A自己的MAC B 地址.A收到B的 ...
- [shell]查找网段内可用IP地址
#网段可用IP地址 #!/bin/sh ip= " ]; do .$ip -c |grep -q "ttl=" && echo "10.86.8 ...
- linux 查看网段内所有IP
如有转载,不胜荣幸.http://www.cnblogs.com/aaron-agu/ 方法一: nmap –nsP 192.168.1.0/24 #从192.168.1.0到192.168.1.25 ...
- OpenVPN分配静态IP以及同一网段内IP个数(64个)
说明:简单的来说,同一网段内可用的IP数量只有64个:(不一定正确)最直接的解释就是每个客户端占用两个IP,因为根据IP掩码位/30得知可用的IP就是两个.对于为什么只有64个,下面是官方的解释. 解 ...
- FW Docker为容器分配指定物理网段的静态IP
官方有关于网桥和IP配置的文档地址:https://docs.docker.com/articles/networking/ 1.宿主机(系统采用ubuntu-14.04.1-server-amd64 ...
- 浅谈数据库技术,磁盘冗余阵列,IP分配,ECC内存,ADO,DAO,JDBC
整理-----数据库技术,磁盘冗余阵列,IP分配, ECC内存,ADO, DAO,JDBC 1.MySQL MySQL是最受欢迎的开源SQL数据库管理系统,它由 MySQL AB开发.发布和支持.My ...
- 内网ip/公网ip
ip地址初识: 现在的IP网络使用32位地址,以点分十进制表示,如172.16.0.0.地址格式为:IP地址=网络地址+主机地址 或 IP地址=网络地址+子网地址+主机地址. IP地址类型 最初设计互 ...
- [转]详述DHCP服务器的三种IP分配方式
DHCP就是动态主机配置协议(Dynamic Host Configuration Protocol),它的目的就是为了减轻TCP/IP网络的规划.管理和维护的负担,解决IP地址空间缺乏问题.这种网络 ...
随机推荐
- map、filter、forEach、reduce数组方法的封装
1.map方法的封装 Array.prototype.mapAlley = function(callback){ //获取调用mapAlley这个方法的数组 let arr = thi ...
- 20130330 printf数组改变 数组指针便利二维数组 二级指针遍历二维数组 ZigZag
1.为什么printf之后数组的值会改变? #include<stdio.h> ; int * Zigzag() { ,j=,limit=; ; ; int a[N][N]; int (* ...
- hbase 集群搭建(公司内部测试集群)
我用的是cdh4.5版本:配置文件:$HBASE_HOME/conf/hbase-env.shexport JAVA_HOME=$JAVA_HOMEexport JAVA_HOME=/home/had ...
- [CERC2017]Gambling Guide
题目 看起来非常随机游走,但是由于我们可以停在原地,所以变得不是非常一样 设\(f_x\)表示从\(x\)到\(n\)的期望距离 如果我们提前知道了\(f\),那么我们随机到了一张到\(y\)的车票, ...
- 9.spark Core 进阶2--Cashe
RDD Persistence One of the most important capabilities in Spark is persisting (or caching) a d ...
- Largest Submatrix
Largest Submatrix 给出一个\(n\times m\)的网格,网格里只放有字符a,b,c,d,w,x,,z,现在你可以将其中的w换成a,b,把x换成b,c,把y换成a,c,把z换成a, ...
- MySQL安装pdf介绍
pdf地址:https://files.cnblogs.com/files/pygo/mysql%E5%AE%89%E8%A3%85.pdf
- linux下怎么安装Go开发环境?linux部署golang
linux下怎么安装Go开发环境?linux部署golang 0.请自行安装SSH远程工具 1. SSH远程登录你的linux服务器 2. yum install mercurial安装 me ...
- JS typeof() parseInt() parseFloat()
判断变量的数据类型:typeof() 使用一元运算符typeof(),可以测试一个变量的类型. typeof()测试的结果是一个类型字符串. typeof()的结果字符串有几种情况: “string” ...
- latex ctex 的section不能写中文, /href
问题描述:再使用超链接 /href 后发现section{}不能写入中文,以前是好使的,经过查询验证,需要在引导区里加入 \hypersetup{CJKbookmarks=true} 即可恢复正常.