您的位置:首页 > 编程语言 > PHP开发

php 进行子网换算(二进制,解决32位/64位系统超出最大int)

2016-06-24 17:39 495 查看
2位和64位子网换算,还是跟我之前发布的那个一样的问题,ip转换成int超出了系统最大限制,找了很久终于找到了一种以二进制计算的方式,分享给大家

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Subnet extends MY_Controller{
public $ip = array();
public $mask = array();

//加载函数
function __construct()
{
parent::__construct();
}

public function index()
{
$this->load->view('tools/subnet_conversion.html');
}

public function show($ip,$mask){
//初始化mask and ip
$this->setmask($mask);
$this->ip = explode('.', $ip);
//计算可用数量通过子网掩码计算总数
foreach($this->mask as $k=>$v){
$newmask .= $v;
}
$num = substr_count($newmask,'0');
//最大值
$data['max'] = pow(2,$num)-2;
$data['net'] = $this->net();
$data['mask'] = $this->mask() ;
$data['range1'] = $data['max'] > 0?$this->onerange():'';
$data['range2'] = $data['max'] > 0?$this->endrange():'';

//最小ip的32位二进制
foreach(explode('.',$data['range1']) as $k=>$v){
$ip2 = decbin($v);
$allip2 .= str_pad($ip2,8,"0",STR_PAD_LEFT);
}

$endallip = $this->binary_plus($allip2, decbin(rand(0,$data['max']-1)));
$ip_1 = bindec(substr($endallip,"0",8));
$ip_2 = bindec(substr($endallip,"8",8));
$ip_3 = bindec(substr($endallip,"16",8));
$ip_4 = bindec(substr($endallip,"24",8));
$newip = $ip_1.'.'.$ip_2.'.'.$ip_3.'.'.$ip_4;
$data['rand'] = $data['max'] > 0?$newip:'-';
$data['max'] = $data['max'] > 0?$data['max']:0;
echo json_encode($data);

}

//初始化mask
public function setmask($mask){
if (is_numeric($mask)) {
//如果参数为数值掩码
for ($i = 0; $i < $mask; $i++) {
$mask2.='1';
}
for ($i = $mask; $i < 32; $i++) {
$mask2.='0';
}
$this->mask[] = substr($mask2,"0",8);
$this->mask[] = substr($mask2,"8",8);
$this->mask[] = substr($mask2,"16",8);
$this->mask[] = substr($mask2,'24',8);

}else {
$mask22 = explode('.', $mask);
foreach($mask22 as $key=>$val){
$Ip = decbin($val);
$bIp .= str_pad($Ip,8,"0",STR_PAD_LEFT);
}
$this->mask[] = substr($bIp,"0",8);
$this->mask[] = substr($bIp,"8",8);
$this->mask[] = substr($bIp,"16",8);
$this->mask[] = substr($bIp,'24',8);

}
}

//第一个可用地址
public function onerange(){
for ($i=0;$i<3;$i++){
$newone .= $this->startIp($this->ip[$i],$this->mask[$i]);
$newone .= '.';
}
$ip_4 = $this->startIp($this->ip[3],$this->mask[3]);
$newone .= ++$ip_4;
return $newone;
}

//最后一个可用
public function endrange(){
for($i=0;$i<3;$i++){
$newend .= $this->endIp($this->ip[$i],$this->mask[$i]);
$newend .= '.';
}
$ip_4 = $this->endIp($this->ip[3],$this->mask[3]);
$newend .= --$ip_4;
return $newend;
}

//return 网络地址
public function net(){
for($i=0;$i<4;$i++){
$newnet .= $this->startIp($this->ip[$i],$this->mask[$i]);
if($i != 3) $newnet.='.';
}
return $newnet;
}

//网络地址转换
public function startIp($str,$bSub){
$bIp = decbin($str);
$bIp = str_pad($bIp,8,"0",STR_PAD_LEFT);
$sIp = bindec($bIp & $bSub);
return $sIp;
}

//结束ip转换
public function endIp($str,$bSub){
$bIp = decbin($str);
$bIp = str_pad($bIp,8,"0",STR_PAD_LEFT);
$eIp = bindec($bIp | $this->revBin($bSub));
return $eIp;
}

//掩码
public function mask(){
for ($i=0;$i<4;$i++){
$newmask .= bindec($this->mask[$i]);
if($i!=3) $newmask .= '.';
}
return $newmask;
}

public function revBin($s){
$p=array('0','1','2');
$r=array('2','0','1');
return str_replace($p,$r,$s);
}

//二进制加法运算
public function binary_plus($binstr1, $binstr2) {
$bin_arr1 = str_split($binstr1);
$bin_arr2 = str_split($binstr2);
$arr_len1 = count($bin_arr1);
$arr_len2 = count($bin_arr2);
$sum_arr = array();
if ($arr_len1 < $arr_len2) {
$short_arr = &$bin_arr1;
} else {
$short_arr = &$bin_arr2;
}
//将两个数组的长度补到一样长,短数组在前面补0
for ($i = 0; $i < abs($arr_len1 - $arr_len2); $i++) {
array_unshift($short_arr, 0);
}
//进位标记
$carry = 0;
for ($i = count($bin_arr1)-1; $i >= 0; $i--){
$result = $bin_arr1[$i] + $bin_arr2[$i] + $carry;
switch ($result) {
case 0:
array_unshift($sum_arr, 0);
$carry = 0;
break;
case 1:
array_unshift($sum_arr, 1);
$carry = 0;
break;
case 2:
array_unshift($sum_arr, 0);
$carry = 1;
break;
case 3:
array_unshift($sum_arr, 1);
$carry = 1;
break;
default:
die();
}
}
if($carry == 1) {
array_unshift($sum_arr, 1);
}
return implode("", $sum_arr);
}

}

/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php int最大限制