Getting list IPs from CIDR notation in PHP

前端 未结 13 1333
慢半拍i
慢半拍i 2020-12-08 05:38

Is there a way (or function/class) to get the list of IP addresses from a CIDR notation?

For example, I have 73.35.143.32/27 CIDR and want to get the list of all IP\

相关标签:
13条回答
  • 2020-12-08 05:52

    Hej. I also needed this function and I edit 1 other to return me list of all IP addresses from range. This will return list of IP addresses from CIDR Notation. Enjoy it ;)

    <?php 
    
        $ip_addr_cidr = "192.256.0.0/16";
        $ip_arr = explode('/', $ip_addr_cidr);
    
        $bin = '';
        for($i=1;$i<=32;$i++) {
            $bin .= $ip_arr[1] >= $i ? '1' : '0';
        }
        $ip_arr[1] = bindec($bin);
    
        $ip = ip2long($ip_arr[0]);
        $nm = ip2long($ip_arr[1]);
        $nw = ($ip & $nm);
        $bc = $nw | (~$nm);
    
        echo "Number of Hosts:    " . ($bc - $nw - 1) . "<br/>";
        echo "Host Range:         " . long2ip($nw + 1) . " -> " . long2ip($bc - 1) . "<br/>". "<br/>";
    
        for($zm=1;($nw + $zm)<=($bc - 1);$zm++)
            {
            echo long2ip($nw + $zm).  "<br/>";
            }
    
        ?>
    
    0 讨论(0)
  • 2020-12-08 05:59

    Highly recommend this PHP Lib: https://github.com/S1lentium/IPTools

    It can manipulate network easily with many functions.

    e.g. Iterate over Network IP adresses:

    $network = Network::parse('192.168.1.0/24');
    foreach($network as $ip) {
        echo (string)$ip . '<br>';
    }
    
    // output:
    192.168.1.0
    ...
    192.168.1.255
    
    0 讨论(0)
  • 2020-12-08 05:59

    this returns an array of ips:

    function get_list_ip($ip_addr_cidr){
        $ip_arr = explode("/", $ip_addr_cidr);    
        $bin = "";
    
        for($i=1;$i<=32;$i++) {
            $bin .= $ip_arr[1] >= $i ? '1' : '0';
        }
    
        $ip_arr[1] = bindec($bin);
    
        $ip = ip2long($ip_arr[0]);
        $nm = $ip_arr[1];
        $nw = ($ip & $nm);
        $bc = $nw | ~$nm;
        $bc_long = ip2long(long2ip($bc));
    
        for($zm=1;($nw + $zm)<=($bc_long - 1);$zm++)
        {
            $ret[]=long2ip($nw + $zm);
        }
        return $ret;
    }
    
    0 讨论(0)
  • 2020-12-08 05:59

    Fixed version of Kosmonaft script:

    function get_list_ip($ip_addr_cidr){
    
            $ip_arr = explode("/", $ip_addr_cidr);    
            $bin = "";
    
            for($i=1;$i<=32;$i++) {
                $bin .= $ip_arr[1] >= $i ? '1' : '0';
            }
    
            $ip_arr[1] = bindec($bin);
    
            $ip = ip2long($ip_arr[0]);
            $nm = $ip_arr[1];
            $nw = ($ip & $nm);
            $bc = $nw | ~$nm;
            $bc_long = ip2long(long2ip($bc));
    
            echo "Number of Hosts:    " . ($bc_long - $nw - 1) . "<br/>";
            echo "Host Range:         " . long2ip($nw + 1) . " -> " . long2ip($bc - 1) . "<br/>". "<br/>";
    
            for($zm=1;($nw + $zm)<=($bc_long - 1);$zm++)
            {
                echo long2ip($nw + $zm).  "<br/>";
            }
        }
    
    0 讨论(0)
  • 2020-12-08 06:02

    I come up with a better idea

    $ip_from= long2ip(ip2long($ip)& (-1<<(32-$net_mask)));
    $ip_to= long2ip(ip2long($ip)| (~(-1<<(32-$net_mask))));
    

    P.S:$ip is a ipv4 address like 60.12.34.5;$net_mask is a int net mask like 25;

    it's very fast because of the bit shift operation

    0 讨论(0)
  • 2020-12-08 06:02

    I had some problems with the previous versions, various PHP errors like undefined offset etc.

    I found what I think is a better way to do it without the errors as detailed below.

    This takes IPV4 CIDR notation IP addresses and can be used to get the start/end IP addresses of the CIDR range or count the total number of IP addresses in a database of IP addresses.

        $count = 0;
        $result = $sia_db_con->query("SELECT `ip_address` FROM `ip4` WHERE `ip_ban_active`='True' ORDER BY ip4.added ASC");
    while ($row = $result->fetch_array()) {
        $pos = strpos($row[0], "/");
        $ip_arr = [0 => substr($row[0], 0, $pos), 1 => substr($row[0], $pos+1)];
        $start = cidr2ip($ip_arr)[0];
        $end = cidr2ip($ip_arr)[1];
        $count = $count + (ip2long($end) - ip2long($start)) + 1;
    }
        unset($result, $row, $pos, $ip_arr, $start, $end, $range);
    
    function cidr2ip($cidr) {
        $start = ip2long($cidr[0]);
        $nm = $cidr[1];
        $num = pow(2, 32 - $nm);
        $end = $start + $num - 1;
        $range = [0 => $cidr[0], 1 => long2ip($end)];
        unset($start, $nm, $num, $end);
        return $range;
    }
    

    The secret here is the way in which I create the $ip_arr variable. Rather than using PHP explode, I set the array dimensions manually for each IP address. This is of course a database version of the code and cycles through all IP addresses in the database which meet the search criteria.

    0 讨论(0)
提交回复
热议问题