Jump to content
新域网络技术论坛

网络技术中子网掩码算法


Jamers
 Share

Recommended Posts

网络架构中常常要使用到子网掩码,手工计算相对麻烦,能不能让程序来计算出来呢?

 

目前代码生成的数据为可使用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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...