Jamers Posted January 19, 2015 Report Share Posted January 19, 2015 网络架构中常常要使用到子网掩码,手工计算相对麻烦,能不能让程序来计算出来呢? 目前代码生成的数据为可使用IP地址 <?php class cls_mask { /** * 子网掩码算法? * Jamers 2015.1.17 */ static function calc($ip) { $out = array(); $im = explode('/',$ip); $ia = explode('.',$im[0]); if (strpos($im[1],'.')===false) { $mv = intval($im[1]); }else{ $mv = self::getmaskval($im[1]); } $mask = self::getmask($mv); //默认C类 $count = 1; if ($mv<16) { //A类 $count = 3; }else if ($mv<24) { //B类 $count = 2; } $res = array(); $bin = array(); foreach($ia as $k=>$v) { $t = decbin(intval($v)); $t = str_repeat('0',8-strlen($t)).$t; $tmp = bindec($t) & intval($mask[$k]); $res[] = $tmp; $t = decbin($tmp); $t = str_repeat('0',8-strlen($t)).$t; $bin[] = $t; } //if ($mv<=) $start = str_repeat('0',32-$mv-1).'1'; $end = str_repeat('1',32-$mv-1).'0'; $flag = substr(implode('',$bin),0,$mv); $p = $mv-(4-$count)*8; $d = array(); if ($p) { $fp = substr($flag,0,-1*$p); $ss = 0; $se = bindec(str_repeat('1',$p)); for ($i=$ss;$i<=$se;$i++) { $aa = decbin($i); $add = str_repeat('0',$p-strlen($aa)).$aa; $ps = self::bintoip($fp.$add.$start); $pe = self::bintoip($fp.$add.$end); //echo "{$ps}-{$pe},(".self::getnums($ps,$pe).")<br>"; $d[] = "{$ps}-{$pe},(".self::getnums($ps,$pe).")"; } }else{ $ps = self::bintoip($flag.$start); $pe = self::bintoip($flag.$end); //echo "{$ps}-{$pe},(".self::getnums($ps,$pe).")<br>"; $d[] = "{$ps}-{$pe},(".self::getnums($ps,$pe).")"; } //echo "<br>{$count},{$p}<br>"; $list = implode('.',$res).'/'.implode('.',$mask).'('.$mv.')'; $out['list'] = $list; $out['data'] = $d; return $out; } static function bintoip($bin) { $ip = str_split($bin,8); $r = array(); foreach ($ip as $v) { $r[] = bindec($v); } return implode('.',$r); } static function getmask($n) { //根据子网掩码值取子网掩码 if ($n>32) $n = 32; $res = array(); $t = str_repeat('1',$n).str_repeat('0',32-$n); $tmp = str_split($t,8); foreach($tmp as $v) { $res[]=bindec($v); } return $res; } static function getmaskval($mask) { //取子网掩码值 $tmp = explode('.',$mask); $res = array(); foreach($tmp as $v) { $t = decbin(intval($v)); $t = str_repeat('0',8-strlen($t)).$t; $res[] = $t; } $t = implode('',$res); return strrpos($t,'1')+1; } static function getnums($ip1,$ip2) { /** * 取两个IP间的可用IP数 */ $n1 = self::getipval($ip1); $n2 = self::getipval($ip2); return abs($n1-$n2)+1; } static function getipval($ip) { /** * 将IP数值化 */ $r = explode('.',$ip); $val = 0; foreach($r as $k=>$v) { $val += $v*(pow(254,abs($k-3))); } return $val; } } $sp = '192.168.1.100/24'; if (isset($_REQUEST['i'])) $sp = $_REQUEST['i']; $pp = cls_mask::calc($sp); var_dump($pp); ?> $i = '192.168.1.0/29';的话返回结果如下: array(2) { ["list"]=> string(31) "192.168.1.0/255.255.255.248(29)" ["data"]=> array(32) { [0]=> string(27) "192.168.1.1-192.168.1.6,(6)" [1]=> string(28) "192.168.1.9-192.168.1.14,(6)" [2]=> string(29) "192.168.1.17-192.168.1.22,(6)" [3]=> string(29) "192.168.1.25-192.168.1.30,(6)" [4]=> string(29) "192.168.1.33-192.168.1.38,(6)" [5]=> string(29) "192.168.1.41-192.168.1.46,(6)" [6]=> string(29) "192.168.1.49-192.168.1.54,(6)" [7]=> string(29) "192.168.1.57-192.168.1.62,(6)" [8]=> string(29) "192.168.1.65-192.168.1.70,(6)" [9]=> string(29) "192.168.1.73-192.168.1.78,(6)" [10]=> string(29) "192.168.1.81-192.168.1.86,(6)" [11]=> string(29) "192.168.1.89-192.168.1.94,(6)" [12]=> string(30) "192.168.1.97-192.168.1.102,(6)" [13]=> string(31) "192.168.1.105-192.168.1.110,(6)" [14]=> string(31) "192.168.1.113-192.168.1.118,(6)" [15]=> string(31) "192.168.1.121-192.168.1.126,(6)" [16]=> string(31) "192.168.1.129-192.168.1.134,(6)" [17]=> string(31) "192.168.1.137-192.168.1.142,(6)" [18]=> string(31) "192.168.1.145-192.168.1.150,(6)" [19]=> string(31) "192.168.1.153-192.168.1.158,(6)" [20]=> string(31) "192.168.1.161-192.168.1.166,(6)" [21]=> string(31) "192.168.1.169-192.168.1.174,(6)" [22]=> string(31) "192.168.1.177-192.168.1.182,(6)" [23]=> string(31) "192.168.1.185-192.168.1.190,(6)" [24]=> string(31) "192.168.1.193-192.168.1.198,(6)" [25]=> string(31) "192.168.1.201-192.168.1.206,(6)" [26]=> string(31) "192.168.1.209-192.168.1.214,(6)" [27]=> string(31) "192.168.1.217-192.168.1.222,(6)" [28]=> string(31) "192.168.1.225-192.168.1.230,(6)" [29]=> string(31) "192.168.1.233-192.168.1.238,(6)" [30]=> string(31) "192.168.1.241-192.168.1.246,(6)" [31]=> string(31) "192.168.1.249-192.168.1.254,(6)" } } Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now