## PHP: Convert IP Range to CIDR

PHP: Convert CIDR to ipaddress range

PHP: check valid ipaddress or CIDR notation range

This function work done with small IP range ex: 111.234.23.1 – 11.234.23.243

Solution 1

<?php
/**
* @author phptuts
*/

function ip2cidr($ips) {$return = array();
$num = ip2long($ips[1]) - ip2long($ips[0]) + 1;$bin = decbin($num);$chunk = str_split($bin);$chunk = array_reverse($chunk);$start = 0;

while ($start < count($chunk))
{
if ($chunk[$start] != 0)
{
$start_ip = isset($range) ? long2ip(ip2long($range[1]) + 1) :$ips[0];
$range = cidr2ip($start_ip . '/' . (32 - $start));$return[] = $start_ip . '/' . (32 -$start);
}
$start++; } return$return;
}
?>

Example of usage:

<?
$ips = array('121.0.47.0', '121.0.47.222'); print_r(ip2cidr($ips));
?>

result:

Array
(
[0] => 121.0.47.0/32
[1] => 121.0.47.1/31
[2] => 121.0.47.3/30
[3] => 121.0.47.7/29
[4] => 121.0.47.15/28
[5] => 121.0.47.31/26
[6] => 121.0.47.95/25
)

Solution 2

<?
function ip2cidr_2($ips) {$return = array();
$num = ip2long($ips[1]) - ip2long($ips[0]) + 1;$bin = decbin($num);$chunk = str_split($bin);$chunk = array_reverse($chunk);$start = 32 - count($chunk) + 1; while ($start <= 32)
{
if ($chunk[32 -$start] != 0)
{

$start_ip = isset($range) ? long2ip(ip2long($range[1]) + 1) :$ips[0];
$range = cidr2ip($start_ip . '/' . ($start));$return[] = $start_ip . '/' . ($start);
}
$start++; } return$return;
}
?>

Example of usage:

<?
$ips = array('121.0.47.0', '121.0.47.222'); print_r(ip2cidr_2($ips));
?>

result:

Array
(
[0] => 121.0.47.0/25
[1] => 121.0.47.128/26
[2] => 121.0.47.192/28
[3] => 121.0.47.208/29
[4] => 121.0.47.216/30
[5] => 121.0.47.220/31
[6] => 121.0.47.222/32
)

Solution 3

<?
function _cidr8($ips) {$ip04 = ip2long($ips[0]) & 255;$ip14 = ip2long($ips[1]) & 255;$log0 = log($ip04, 2);$log1 = log($ip14, 2);$return = $log1 > floor($log1) ? floor($log1) : ($log1 - 1);
if ($return > ceil($log0))
{
return $return = pow(2,$return);
} else
{
$mid = (pow(2,$return) + pow(2, $return + 1)) / 2; if ($ip14 > $mid &&$ip04 < $mid) { return$return = $mid; } else { if ($ip14 > $mid) {$mid2 = $mid;$end = pow(2, $return + 1);$mid = ($mid2 +$end) / 2;
if ($ip14 >$mid && $ip04 <$mid)
{
return $return =$mid;
} elseif ($ip04 >$mid)
{
$mid2 =$mid;
$mid = ($mid + $end) / 2; if ($ip14 > $mid &&$ip04 < $mid) { return$return = $mid; } elseif ($ip04 > $mid) {$mid2 = $mid; } else {$end = $mid; } } else {$end = $mid; } } else {$mid2 = $mid;$end = pow(2, $return);$mid = ($mid2 +$end) / 2;
if ($ip14 >$mid && $ip04 <$mid)
{
return $return =$mid;
} elseif ($ip04 >$mid)
{
$end =$mid;
$mid = ($mid2 + $end) / 2; if ($ip14 > $mid &&$ip04 < $mid) { return$return = $mid; } elseif ($ip04 > $mid) {$end = $mid; } else {$mid2 = $mid; } } else {$end = $mid;$mid2 = pow(2, $return); } }$mid1 = ($mid2 +$end) / 2;
if ($ip14 >$mid1 && $ip04 <$mid1)
{
return $return =$mid1;
} elseif ($ip14 >$mid1)
{
return $return = ($mid1 + $end) / 2; } else { return$return = ($mid1 +$mid2) / 2;
}
}
}
}

function ip2cidr_3($ips) {$ip04 = ip2long($ips[0]) & 255;$ip14 = ip2long($ips[1]) & 255;$prefix = ip2long($ips[0]) & 4294967040; if($ip04==0 && $ip14==255) return long2ip($prefix)."/24";
$div1long =$prefix | _cidr8($ips); return array_merge(ip2cidr(array($ips[0], long2ip($div1long - 1))), ip2cidr_2(array(long2ip ($div1long), $ips[1]))); } ?> Example of usage: <?$ips = array('222.0.47.1', '222.0.47.243');
print_r(ip2cidr_3($ips)); ?> result: Array ( [0] => 222.0.47.1/32 [1] => 222.0.47.2/31 [2] => 222.0.47.4/30 [3] => 222.0.47.8/29 [4] => 222.0.47.16/28 [5] => 222.0.47.32/27 [6] => 222.0.47.64/26 [7] => 222.0.47.128/26 [8] => 222.0.47.192/27 [9] => 222.0.47.224/28 [10] => 222.0.47.240/30 ) Solution 4 <? function ip2cidr_4($ips)
{
$ip04 = ip2long($ips[0]) & 255;
if (log($ip04, 2) == floor(log($ip04, 2)) && $ip04 != 1) return ip2cidr_2($ips);
$sub04 = pow(2, floor(log($ip04, 2)) + 1) - 1;
$div1long = (ip2long($ips[0]) & 4294967040) | $sub04;$div1 = long2ip($div1long);$range1 = ip2cidr_2(array($ips[0],$div1));
$ip14 = ip2long($ips[1]) & 255;
$sub14 = pow(2, floor(log($ip14, 2))) - 1;
$div2long = (ip2long($ips[1]) & 4294967040) | $sub14;$div2 = long2ip($div2long);$range2 = ip2cidr(array(long2ip($div1long + 1),$div2));
$range3 = ip2cidr_2(array(long2ip($div2long + 1), $ips[1])); return array_merge($range1, $range2,$range3);
}
?>

Example of usage:

<?
$ips = array('222.0.47.1', '222.0.47.243'); print_r(ip2cidr_4($ips));
?>

result:

Array
(
[0] => 222.0.47.1/32
[1] => 222.0.47.2/31
[2] => 222.0.47.4/30
[3] => 222.0.47.8/29
[4] => 222.0.47.16/28
[5] => 222.0.47.32/27
[6] => 222.0.47.64/26
[7] => 222.0.47.128/26
[8] => 222.0.47.192/27
[9] => 222.0.47.224/28
[10] => 222.0.47.240/30
)

Bonus
3 functions to check 8bits IP range

<?
function check_8bits_range($ips){ return (ip2long($ips[0]) ^ ip2long($ips[1]))<256; } function check_8bits_range_2($ips)
{
return (ip2long($ips[0]) & 4294967040)==(ip2long($ips[1]) & 4294967040);
}

function check_8bits_range_3($ips) { return (ip2long($ips[0]) >> 8) == (ip2long($ips[1]) >> 8); } ?> EX: <?$ips = array('222.0.47.1', '222.0.47.243');
var_dump(check_8bits_range(\$ips));//true
?>

Note:

bindec('11111111111111111111111100000000') = 4294967040

Continuing…