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地址空间缺乏问题.这种网络 ...
随机推荐
- 转: div:给div加滚动条 div的滚动条设置
div 的滚动条问题: 两种方法: 一. <div style=" overflow:scroll; width:400px; height:400px;”></div&g ...
- spring关于bean的一些配置说明
<context:annotation-config> 是用于激活那些已经在spring容器里注册过的bean上面的注解.该标签主要向容器中掩式定的注了 AutowiredAnnotati ...
- 线性可分SVM中线性规划问题的化简
在网上找了许多关于线性可分SVM化简的过程,但似乎都不是很详细,所以凭借自己的理解去详解了一下. 线性可分SVM的目标是求得一个超平面(其实就是求w和b),在其在对目标样本的划分正确的基础上,使得到该 ...
- 5-Python操作MySQL步骤
1.引入模块 在py文件中引入pymysql模块 from pymysql import *(connect) 2.创建connection连接对象 conn=connect(参数列表) 参数host ...
- 用CSS做导航菜单的4个理由
导航结构在网站设计中是起到决定性作用的,导航菜单/栏常常通过颜色.排版.形状和一些图片来帮助网站创造更好的视觉和感受,它是网页设计的关键元素.虽然网站导航菜单的外观是网页设计中关系到整个设计成败与否的 ...
- DOM基础及事件基础
DOM:功能:控制html文档的内容代码:获取页面标签(元素)对象 Element document.getElementById("id值"):通过元素id获取元素对象操作Ele ...
- MySQL数据库之DQL(数据查询语言)
1.MySQL之DQL查询AS CONCAT LIKE的使用 (1)select 列名1,列名2,...... from 表名 [where 条件] 查询所有字段用*,不带where条件的话,就会把表 ...
- PHP算法之宝石与石头
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字符都是字母 ...
- vue 兄弟组件的传值
handleLetterClick方法,采用emit 传递给父组件 父组件触发的方法: handleLetterChange方法: 父组件传递给子组件: CityList组件: 兄弟组件的传值可以 ...
- scala中异常捕获与处理简单使用
import java.io.IOException /** * 异常捕获与处理 */ object excepitonUse { def main(args: Array[String]): Uni ...