Getting list IPs from CIDR notation in PHP
Asked Answered
I

14

23

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's in this notation. Any suggestions?

Thank you.

Issus answered 8/2, 2011 at 10:10 Comment(1)
see matching an IP to a CIDR mask in php5?Biomedicine
K
39

I'll edit the aforementioned class to contain a method for that. Here is the code I came up with that might help you until then.

function cidrToRange($cidr) {
  $range = array();
  $cidr = explode('/', $cidr);
  $range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
  $range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
  return $range;
}
var_dump(cidrToRange("73.35.143.32/27"));

//////////////////OUTPUT////////////////////////
// array(2) {
//   [0]=>
//   string(12) "73.35.143.32"
//   [1]=>
//   string(12) "73.35.143.63"
// }
/////////////////////////////////////////////////

Returns the low end of the ip range as the first entry in the array, then returns the high end as the second entry.

Ketosis answered 2/5, 2011 at 14:54 Comment(3)
I edited the CIDR class to contain method that will give you the results you're looking for. I think you may also want to take a look at the IPisWithinRange() method.Ketosis
I fail to see how this is the correct answer. The OP ask for the list of all IP's in this notation, this function only extract the low+high end.Enlistee
It answers the question, Dr.GZZ , because it provides the low and high ends of a range, which then allows anyone to know whats between. Returning a full array of IPs is both impractical, and can easily crash PHP with a low netmask.Bryozoan
P
10

Well, it's a bitmask - 73.35.143.32/27 means that 27 bits are the network mask, and the rest is available for assigning to the nodes in the network:

73.35.143.32

in binary is this (dots shown for legibility):

01001001.00100011.10001111.00100000

The netmask is 27 bits:

11111111.11111111.11111111.11100000

So you can just AND them together and get this:

01001001.00100011.10001111.001 00000
 network prefix (27 bits)     | node address (5 bits)

From here, you can just enumerate all the combinations in the node address (00000 is 0, 11111 is 31, so a simple loop is enough), and you'll have all the available hosts.

Converting this pseudocode to PHP is left as an exercise to the reader ;)

Oh, and the obligatory deprecation warning: IPv4 is now full, consider also IPv6.

Plenteous answered 8/2, 2011 at 10:21 Comment(1)
If you are not looking to include the network address and the broadcast address, then be sure to exclude 0 (network address) and 31 (broadcast address)Smithsonite
W
8

Here is one fast 64bits function to do it, please comment the return line you don't need. Accepting any valid Ipv4 with or without valid CIDR Routing Prefix for example 63.161.156.0/24 or 63.161.156.0

<?php
function cidr2range($ipv4){
if ($ip=strpos($ipv4,'/'))
{$n_ip=(1<<(32-substr($ipv4,1+$ip)))-1;   $ip_dec=ip2long(substr($ipv4,0,$ip)); }
else
{$n_ip=0;                                   $ip_dec=ip2long($ipv4);             }
$ip_min=$ip_dec&~$n_ip;
$ip_max=$ip_min+$n_ip;
#Array(2) of Decimal Values Range
return [$ip_min,$ip_max];
#Array(2) of Ipv4 Human Readable Range
return [long2ip($ip_min),long2ip($ip_max)];
#Array(2) of Ipv4 and Subnet Range
return [long2ip($ip_min),long2ip(~$n_ip)];
#Array(2) of Ipv4 and Wildcard Bits
return [long2ip($ip_min),long2ip($n_ip)];
#Integer Number of Ipv4 in Range
return ++$n_ip;
}

To run fast the function don't check input but formally it should be a string matching the following regex

#^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$#

If you want to verify the input before using the function

<?php
if (is_string($ipv4) && preg_match('#^(?:((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))\.((?:0)|(?:2(?:(?:[0-4][0-9])|(?:5[0-5])))|(?:1?[0-9]{1,2}))(?:/((?:(?:0)|(?:3[0-2])|(?:[1-2]?[0-9]))))?)$#',$ipv4))
{
#This is a valid ipv4 with or without CIDR Routing Prefix
$result=cidr2range($ipv4);
print_r($result);
}

To get the full range as an array for a given IP (with or without CIDR Routing Prefix) you can use the following code but be carefull because for example 25.25.25.25/16 return an array with 65536 elements and you can easily run out of memory using a smaller Routing Prefix

<?php
$result=cidr2range($ipv4);
for($ip_dec=$result[0];$ip_dec<=$result[1];$ip_dec++)
$full_range[$ip_dec]=long2ip($ip_dec);
print_r($full_range);

To fast check if a given ipv4 is matching a given CIDR you can do it inline like in this example

<?php
$given_cidr='55.55.55.0/24';
$given_ipv4='55.55.55.55';
if(($range=cidr2range($given_cidr)) &&
($check=ip2long($given_ipv4))!==false &&
$check>=$range[0] && $check<=$range[1])
{
echo 'Yes, '.$given_ipv4.' is included in '.$given_cidr;
}
else
{
echo 'No, '.$given_ipv4.' is not included in '.$given_cidr;
}

To fast check if a given ipv4 is matching a given array of IP (with or without CIDR Routing Prefix)

<?php
#This code is checking if a given ip belongs to googlebot
$given_ipv4='74.125.61.208';
$given_cidr_array=['108.59.93.43/32','108.59.93.40/31','108.59.93.44/30','108.59.93.32/29','108.59.93.48/28','108.59.93.0/27','108.59.93.64/26','108.59.93.192/26','108.59.92.192/27','108.59.92.128/26','108.59.92.96/27','108.59.92.0/27','108.59.94.208/29','108.59.94.192/28','108.59.94.240/28','108.59.94.128/26','108.59.94.16/29','108.59.94.0/28','108.59.94.32/27','108.59.94.64/26','108.59.95.0/24','108.59.88.0/22','108.59.81.0/27','108.59.80.0/24','108.59.82.0/23','108.59.84.0/22','108.170.217.128/28','108.170.217.160/27','108.170.217.192/26','108.170.217.0/25','108.170.216.0/24','108.170.218.0/23','108.170.220.0/22','108.170.208.0/21','108.170.192.0/20','108.170.224.0/19','108.177.0.0/17','104.132.0.0/14','104.154.0.0/15','104.196.0.0/14','107.167.160.0/19','107.178.192.0/18','125.17.82.112/30','125.16.7.72/30','74.125.0.0/16','72.14.192.0/18','77.109.131.208/28','77.67.50.32/27','66.102.0.0/20','66.227.77.144/29','66.249.64.0/19','67.148.177.136/29','64.124.98.104/29','64.71.148.240/29','64.68.64.64/26','64.68.80.0/20','64.41.221.192/28','64.41.146.208/28','64.9.224.0/19','64.233.160.0/19','65.171.1.144/28','65.170.13.0/28','65.167.144.64/28','65.220.13.0/24','65.216.183.0/24','70.32.132.0/23','70.32.128.0/22','70.32.136.0/21','70.32.144.0/20','85.182.250.128/26','85.182.250.0/25','80.239.168.192/26','80.149.20.0/25','61.246.224.136/30','61.246.190.124/30','63.237.119.112/29','63.226.245.56/29','63.158.137.224/29','63.166.17.128/25','63.161.156.0/24','63.88.22.0/23','41.206.188.128/26','12.234.149.240/29','12.216.80.0/24','8.34.217.24/29','8.34.217.0/28','8.34.217.32/27','8.34.217.64/26','8.34.217.128/25','8.34.216.0/24','8.34.218.0/23','8.34.220.0/22','8.34.208.128/29','8.34.208.144/28','8.34.208.160/27','8.34.208.192/26','8.34.208.0/25','8.34.209.0/24','8.34.210.0/23','8.34.212.0/22','8.35.195.128/28','8.35.195.160/27','8.35.195.192/26','8.35.195.0/25','8.35.194.0/24','8.35.192.0/23','8.35.196.0/22','8.35.200.0/21','8.8.8.0/24','8.8.4.0/24','8.6.48.0/21','4.3.2.0/24','23.236.48.0/20','23.251.128.0/19','216.239.32.0/19','216.252.220.0/22','216.136.145.128/27','216.33.229.160/29','216.33.229.144/29','216.34.7.176/28','216.58.192.0/19','216.109.75.80/28','216.74.130.48/28','216.74.153.0/27','217.118.234.96/28','208.46.199.160/29','208.44.48.240/29','208.21.209.0/28','208.184.125.240/28','209.185.108.128/25','209.85.128.0/17','213.200.103.128/26','213.200.99.192/26','213.155.151.128/26','199.192.112.224/29','199.192.112.192/27','199.192.112.128/26','199.192.112.0/25','199.192.113.176/28','199.192.113.128/27','199.192.113.192/26','199.192.113.0/25','199.192.115.80/28','199.192.115.96/27','199.192.115.0/28','199.192.115.128/25','199.192.114.192/26','199.192.114.0/25','199.223.232.0/21','198.108.100.192/28','195.16.45.144/29','192.104.160.0/23','192.158.28.0/22','192.178.0.0/15','206.160.135.240/28','207.223.160.0/20','203.222.167.144/28','173.255.125.72/29','173.255.125.80/28','173.255.125.96/27','173.255.125.0/27','173.255.125.128/25','173.255.124.240/29','173.255.124.232/29','173.255.124.192/27','173.255.124.128/29','173.255.124.144/28','173.255.124.160/27','173.255.124.48/29','173.255.124.32/28','173.255.124.0/27','173.255.124.64/26','173.255.126.0/23','173.255.122.128/26','173.255.122.64/26','173.255.123.0/24','173.255.121.128/26','173.255.121.0/25','173.255.120.0/24','173.255.117.32/27','173.255.117.64/26','173.255.117.128/25','173.255.116.192/27','173.255.116.128/26','173.255.116.0/25','173.255.118.0/23','173.255.112.0/22','173.194.0.0/16','172.102.8.0/21','172.253.0.0/16','172.217.0.0/16','162.216.148.0/22','162.222.176.0/21','180.87.33.64/26','128.177.109.0/26','128.177.119.128/25','128.177.163.0/25','130.211.0.0/16','142.250.0.0/15','146.148.0.0/17'];
echo '<pre>';
$in_range=false;
if (($given_ipv4_dec=ip2long($given_ipv4))!==false)
{
foreach($given_cidr_array as $given_cidr){
if(($range=cidr2range($given_cidr)) &&
$given_ipv4_dec>=$range[0] && $given_ipv4_dec<=$range[1])
{
$in_range=true;
echo $given_ipv4.' matched '.$given_cidr.' ('.join(array_map('long2ip',$range),' - ').")\n";
}
}
}
echo $given_ipv4.' is probably'.($in_range?'':' not').' a Googlebot IP';

hope that these few lines have helped you…

Wax answered 16/2, 2017 at 9:35 Comment(3)
Fantastic - what a proper and thorough explanation, thank you.Kempf
This looks very helpful. Kudos for being thorough!Coroner
The flexibility and options of this script are awesome. Solved all my complex cidr range issues and helped me process why what I had been trying was failing. Huge help!Robinson
I
5

There is small fix - when someone place ip prefix like: 127.0.0.15/26 this function returns bad last IP adress. In this function is at line 4 (starts: $range[1]...) changed $cidr[0] to $range[0] - now its return last IP address good for every IP in range.

function cidrToRange($cidr) {
  $range = array();
  $cidr = explode('/', $cidr);
  $range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
  $range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
  return $range;
}
var_dump(cidrToRange("127.0.0.15/26"));

Before fix:

array(2) {
  [0]=>
  string(9) "127.0.0.0"
  [1]=>
  string(10) "127.0.0.78"
}
string(41) "127.0.0.15/26 >> 2130706432 -> 2130706510"

After fix:

array(2) {
  [0]=>
  string(9) "127.0.0.0"
  [1]=>
  string(10) "127.0.0.63"
}
string(41) "127.0.0.15/26 >> 2130706432 -> 2130706495"
Innuendo answered 16/1, 2017 at 9:44 Comment(2)
This is the write code, if we do check the above accepted code with this example, it will not work. 110.143.0.55/16. Thank you Flip :)Dispossess
This is the correct solution. Fixed the accepted solution to avoid a bug dissemination.Tented
B
4

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 . PHP_EOL;
}

// output:
192.168.1.0
...
192.168.1.255
Blindfish answered 2/4, 2020 at 9:22 Comment(0)
B
3

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

Brazier answered 7/4, 2016 at 6:8 Comment(0)
W
2

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;
}
Whitmore answered 30/12, 2015 at 9:38 Comment(0)
S
2

Extension to @jonavon 's answer. If you need flat list of IPs. You can convert his function like below.

function cidrToRange($value) {
    $range = array();
    $split = explode('/', $value);
    if (!empty($split[0]) && is_scalar($split[1]) && filter_var($split[0], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        $rangeStart = ip2long($split[0]) & ((-1 << (32 - (int)$split[1])));
        $rangeEnd = ip2long($split[0]) + pow(2, (32 - (int)$split[1])) - 1;

        for ($i = $rangeStart; $i <= $rangeEnd; $i++) {
            $range[] = long2ip($i);
        }
        return $range;
    } else {
        return $value;
    }
}
Sos answered 26/8, 2016 at 14:58 Comment(1)
Thanks, but to avoid the bug they were talking about in the original function, 2 lines need to be adjusted: $rangeStartIP = long2ip($rangeStart); $rangeEnd = ip2long($rangeStartIP) + pow(2, (32 - (int)$split[1])) - 1;Myo
H
1

I don't believe this class will return a list of IPs, but it does provide some useful methods for working with CIDR blocks.

Hairstreak answered 8/2, 2011 at 10:14 Comment(1)
Unfortunately, this answer is currently useless because your link is dead ("snippet not found"). Please update.Coroner
B
0

I previously wrote an entire Class which handled this task pretty well (for another Language), and thanks to PHP's ip2long(...) method, we don't need to calculate manually in PHP.

But my Unit-Test data can be used to test any of the other answers:

<?php
// Below has "CIDR = Minimum ... Maximum" format.
$validRangeMap = [
    '0.0.0.0/1=0.0.0.0...127.255.255.255',
    '128.0.0.0/2=128.0.0.0...191.255.255.255',
    '192.0.0.0/9=192.0.0.0...192.127.255.255',
    '192.128.0.0/11=192.128.0.0...192.159.255.255',
    '192.160.0.0/13=192.160.0.0...192.167.255.255',
    '192.168.0.0/19=192.168.0.0...192.168.31.255',
    '192.168.32.0/21=192.168.32.0...192.168.39.255',
    '192.168.40.0/23=192.168.40.0...192.168.41.255',
    '192.168.42.0/23=192.168.42.0...192.168.43.255',
    '192.168.44.0/22=192.168.44.0...192.168.47.255',
    '192.168.48.0/20=192.168.48.0...192.168.63.255',
    '192.168.64.0/18=192.168.64.0...192.168.127.255',
    '192.168.128.0/17=192.168.128.0...192.168.255.255',
    '192.169.0.0/16=192.169.0.0...192.169.255.255',
    '192.170.0.0/15=192.170.0.0...192.171.255.255',
    '192.172.0.0/14=192.172.0.0...192.175.255.255',
    '192.176.0.0/12=192.176.0.0...192.191.255.255',
    '192.192.0.0/10=192.192.0.0...192.255.255.255',
    '193.0.0.0/8=193.0.0.0...193.255.255.255',
    '194.0.0.0/7=194.0.0.0...195.255.255.255',
    '196.0.0.0/6=196.0.0.0...199.255.255.255',
    '200.0.0.0/5=200.0.0.0...207.255.255.255',
    '208.0.0.0/4=208.0.0.0...223.255.255.255',
    '224.0.0.0/4=224.0.0.0...239.255.255.255',
    '240.0.0.0/5=240.0.0.0...247.255.255.255',
    '248.0.0.0/6=248.0.0.0...251.255.255.255',
    '252.0.0.0/7=252.0.0.0...253.255.255.255',
    '254.0.0.0/8=254.0.0.0...254.255.255.255',
    '255.0.0.0/9=255.0.0.0...255.127.255.255',
    '255.128.0.0/10=255.128.0.0...255.191.255.255',
    '255.192.0.0/11=255.192.0.0...255.223.255.255',
    '255.224.0.0/12=255.224.0.0...255.239.255.255',
    '255.240.0.0/13=255.240.0.0...255.247.255.255',
    '255.248.0.0/14=255.248.0.0...255.251.255.255',
    '255.252.0.0/15=255.252.0.0...255.253.255.255',
    '255.254.0.0/16=255.254.0.0...255.254.255.255',
    '255.255.0.0/17=255.255.0.0...255.255.127.255',
    '255.255.128.0/18=255.255.128.0...255.255.191.255',
    '255.255.192.0/19=255.255.192.0...255.255.223.255',
    '255.255.224.0/20=255.255.224.0...255.255.239.255',
    '255.255.240.0/21=255.255.240.0...255.255.247.255',
    '255.255.248.0/22=255.255.248.0...255.255.251.255',
    '255.255.252.0/23=255.255.252.0...255.255.253.255',
    '255.255.254.0/24=255.255.254.0...255.255.254.255',
    '255.255.255.0/25=255.255.255.0...255.255.255.127',
    '255.255.255.128/26=255.255.255.128...255.255.255.191',
    '255.255.255.192/27=255.255.255.192...255.255.255.223',
    '255.255.255.224/28=255.255.255.224...255.255.255.239',
    '255.255.255.240/29=255.255.255.240...255.255.255.247',
    '255.255.255.248/30=255.255.255.248...255.255.255.251',
    '255.255.255.252/31=255.255.255.252...255.255.255.253',
    '255.255.255.254/32=255.255.255.254...255.255.255.254',
];

Example

We can test Jonavon's answer, like:

foreach ($validRangeMap as $entry) {
    $expected = preg_split('/(=|(\.\.\.))+/', $entry);
    $actual = cidrToRange($expected[0]);

    if ($actual[0] !== $expected[1]) {
        echo "Test-Failed! '$actual[0]' should be equal '$expected[1]' <br>" . PHP_EOL;
    } else if ($actual[1] !== $expected[2]) {
        echo "Test-Failed! '$actual[1]' should be equal '$expected[2]' <br>" . PHP_EOL;
    } else {
        echo "Tested '$expected[0]' CIDR <br>" . PHP_EOL;
    }
}

function cidrToRange($cidr) {
  $range = array();
  $cidr = explode('/', $cidr);
  $range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
  $range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
  return $range;
}

Note that it passed the tests.

Buchner answered 3/7, 2021 at 7:53 Comment(0)
B
0

The utility cidrl will do this:

$ cidrl 73.35.143.32/27
73.35.143.32
73.35.143.33
73.35.143.34
...
73.35.143.63
Blowfish answered 28/1, 2023 at 5:21 Comment(0)
M
-1

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/>";
        }

    ?>
Munmro answered 25/10, 2012 at 10:15 Comment(2)
on this line, there is error of unknown method, please check $bc = $nw | (~$nm);Dispossess
Looks like there is a syntax error with this script.Shrill
I
-1

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/>";
        }
    }
Infinity answered 19/10, 2015 at 10:12 Comment(0)
S
-1

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.

Stein answered 12/7, 2017 at 19:8 Comment(2)
To get the total number of hosts from a IPV4 CIDR address, you can simply use: $count = 0; $count = $count + pow(2, 32 - substr($ip, strpos($ip, "/") + 1)); Where $ip is a IPV4 CIDR IP Address. You could also loop through multiple IP addresses, from a database for example. This is about as short and simple as I have seen.Stein
To get the total number of hosts from a IPV6 CIDR address, you can simply use: $count = 0; $count = $count + pow(2, 128 - substr($ip, strpos($ip, "/") + 1)); Where $ip is a IPV6 CIDR IP Address. You could also loop through multiple IP addresses, from a database for example.Stein

© 2022 - 2024 — McMap. All rights reserved.