Getting list IPs from CIDR notation in PHP
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.
calculate IP range using PHP and CIDR
As you've already noted, all IPv4 addresses can be converted to numbers using ip2long()
, and converted back using long2ip()
. The critical extra bit I'm not sure you've noticed is that sequential IPs correspond with sequential numbers, so you can manipulate these numbers!
Given a CIDR prefix (e.g, $prefix = 30
for your range), you can calculate the number of IPs in that range using a bit shift operator:
$ip_count = 1 << (32 - $prefix);
And then loop through all the IPs in that range using:
$start = ip2long($start_ip);
for ($i = 0; $i < $ip_count; $i++) {
$ip = long2ip($start + $i);
// do stuff with $ip...
}
PHP How to run list of IP ranges through a CIDR function?
Just loop through the list of ranges, and use array_merge()
to append the results to the collection of all results.
$ranges = [
["start" => "8.8.8.0", "end" => "8.8.8.16"],
["start" => "192.168.10.5", "end" => "192.168.32.255"],
["start" => "10.1.2.32", "end" => "10.1.3.0"]
];
$allCidrs = [];
foreach ($ranges as $range) {
$cidr = iprange2cidr($range["start"], $range["end"]);
$allCidrs = array_merge($allCidrs, $cidr);
}
convert ip short notation into CIDR notation
Note, that I did this as a fun experiment. Your question was a little vague, and you showed no attempt to actually to this yourself. That being said, this function should accomplish what you are wanting. Let me explain what it does:
First thing, checks if last character in the ip is a dot and removes it.
Second, count the number of ranges your IP has.
Third use a switch/case
statement (cleaner than if elseif
IMHO) to determine what to do with the string, based on IP range.
Lastly define the starting range and the ending range and concatenate them.
Finally return result.
<?php
$ips = array();
$ips[0] = '125.45.';
$ips[1] = '201.35.1.';
$ips[2] = '101.135.2';
$ips[3] = '222.122';
$ips[4] = '78.56.21.146';
foreach($ips as $ip){
echo "\n\nNEW IP RANGE: " . convert_ip($ip) . "\n\n";
}
function convert_ip($ip){
$ip = rtrim($ip, '.');
$ip_count = count( explode('.', $ip) );
switch ($ip_count) {
case 1:
$starting_ip = $ip . '.0.0.0';
$ending_ip = $ip . '.255.255.255';
$return_ip = "$starting_ip-$ending_ip";
break;
case 2:
$starting_ip = $ip . '.0.0';
$ending_ip = $ip . '.255.255';
$return_ip = "$starting_ip-$ending_ip";
break;
case 3:
$starting_ip = $ip . '.0';
$ending_ip = $ip . '.255';
$return_ip = "$starting_ip-$ending_ip";
break;
case 4:
$return_ip = $ip;
break;
default:
$return_ip = 'Unknown';
}
return $return_ip;
}
?>
NEW IP RANGE: 125.45.0.0-125.45.255.255
NEW IP RANGE: 201.35.1.0-201.35.1.255
NEW IP RANGE: 101.135.2.0-101.135.2.255
NEW IP RANGE: 222.122.0.0-222.122.255.255
NEW IP RANGE: 78.56.21.146
Check whether or not a CIDR subnet contains an IP address
If only using IPv4:
- use
ip2long()
to convert the IPs and the subnet range into long integers - convert the /xx into a subnet mask
- do a bitwise 'and' (i.e. ip & mask)' and check that that 'result = subnet'
something like this should work:
function cidr_match($ip, $range)
{
list ($subnet, $bits) = explode('/', $range);
if ($bits === null) {
$bits = 32;
}
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
return ($ip & $mask) == $subnet;
}
Convert Array From IP CIDR
Just put the result of the function call into a variable and then print the parts you want
<?php
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;
}
$range = cidrToRange("104.176.0.0/12");
echo 'Staring at ' . $range[0] .'<br>'
echo 'Ending at ' . $range[1] .'<br>'
How to load a list of ip ranges to use it with $allowedIps script?
/*
You need the proper fopen wrapper server settings for reading
URLs using file_get_contents, see the notes at the PHP manual
*/
$allowedIps = explode('\n', file_get_contents('http://my/url/file.txt'));
$userIp = $_SERVER['REMOTE_ADDR'];
if (!in_array($userIp, $allowedIps)) {
exit('Unauthorized');
}
PHP manual for file_get_contents
What is the best way to get /24 blocks from IP address ranges?
Here is the example off of https://www.php.net/manual/en/ref.network.php#74656
A simple and very fast function to check against CIDR.
This example takes into account your range parameter
Here it is (only with arithmetic operators and call only to ip2long () and split() ):
<?php
function ipCIDRCheck ($IP, $CIDR) {
list ($net, $mask) = explode("/", $CIDR);
$ip_net = ip2long ($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);
$ip_ip = ip2long ($IP);
$ip_ip_net = $ip_ip & $ip_mask;
return long2ip($ip_ip_net);
}
$range = "86.111.160.0 - 86.111.175.255";
list($lower,$upper) = explode('-',$range);
$lowerIp = ip2long(trim($lower));
$upperIp = ip2long(trim($upper));
while($lowerIp <= $upperIp){
echo ipCIDRCheck(long2ip($lowerIp),long2ip($lowerIp) .'/24') . "\n\r";
$lowerIp += 255;
}
Related Topics
How to Replace Multiple Items from a Text String in PHP
How to Bulk Update MySQL Data with One Query
Making a Http Get Request with Http-Basic Authentication
Facebook API/PHP - How to Change a User's Profile Image via Fb Graph API
Multi-Byte Safe Wordwrap() Function for Utf-8
Running Imagemagick on Xampp 1.8.3 with Windows 7
Weak Typing in PHP: Why Use Isset at All
PHP - Flushing While Loop Data with Ajax
The Requested Url /Projectname/Users Was Not Found on This Server. Laravel
PHP Hsv to Rgb Formula Comprehension
How Do Check If a PHP Session Is Empty
How to Make Apache Serve Index.PHP Instead of Index.Html
Difference Between File, File_Get_Contents, and Fopen in PHP
PHP Soap Client That Understands Multi-Part Messages