http://blog.xeonxai.com/2008/09/30/91/
This is the text I got from a job recruiter today, to make a PHP script to do as they required for a possible job. Mind you, if you submit the php test to me, and don’t include any NDA, I will most likely post the test, and my results on the internet.
Write a PHP function that determines if an IP address is contained within a list of CIDR blocks. The function should return a boolean. This is the function signature:
function ip_in_cidr_list($ip, $cidr_list)
Example call:
$ip = “216.21.215.10″;
$cidr_list = array(“216.21.208.0/20″, “192.168.0.0/16″);
ip_in_cidr_list($ip, $cidr_list)For bonus points, provide some test code that demonstrates your function is working correctly.
Here is my code results for the test:
/* XEON XAI http://www.xeonxai.com Copyright 2008 Xeon Xai 2008/09/30 04:28PM */ // Construct array for IP addresses to check $ip_list = array(); // Initial IP address to check. $ip_list[] = "216.21.215.10"; $ip_list[] = "192.168.0.1"; // Add in additional random IP addresses to make it a total of 10 that are checked. for ($i = 0; $i <= 7; $i++) { $ip_list[] = RandIPAddress(); } // Construct array for CIDR list. $cidr_list = array(); // Insert into CIDR list. $cidr_list[] = "216.21.208.0/20"; $cidr_list[] = "192.168.0.0/16"; // Do CIDR check. for ($i = 0; $i < count($ip_list); $i++) { $verify = ip_in_cidr_list($ip_list[$i], $cidr_list); if ($verify == false) echo "IP: ".$ip_list[$i]."\n\rFail: Not in range of the CIDR\n\r"; else echo "IP: ".$ip_list[$i]."\n\rPass: In the range of the CIDR\n\r"; } // CIDR checking function function ip_in_cidr_list($ip, $cidr_list) { foreach ($cidr_list as $key=>$value) { // BLOCK ==> $cidr_list[] as $value list($base, $bits) = explode("/", $value); // Split IP address from Mask list($a, $b, $c, $d) = explode(".", $base); // Split each subsection of the IP address. // Break down the bits. $net = ($a << 24) + ($b << 16) + ($c << 8) + $d; $mask = $bits == 0 ? 0 : (~0 << (32 - $bits)); // Low region in IP range. $low = $net & $mask; // High region in IP range. $high = $net | (~$mask & 0xFFFFFFFF); // BLOCK ==> $ip list($a, $b, $c, $d) = explode(".", $ip); // Split each subsection of the IP address. // Break down the bits. $check = ($a << 24) + ($b << 16) + ($c << 8) + $d; // If IP address matches in CIDR range, return true. if ($check >= $low && $check <= $high) return true; } // Will only return false if never first returned as true in above foreach loop. return false; } /* Function to create random IP addresses, that will most likely be out of the range of the scope of the CIDR check system. Most commonly, they will result in a FAIL message. Very few, will result in a PASS message. Tests from ./php | grep Pass: Results from 10 IP address, with 2 static, 8 random. MacBook:cidr Xeon$ /usr/local/php5/bin/php index.php | grep Pass: IP: 216.21.215.10 Pass: In the range of the CIDR IP: 192.168.0.1 Pass: In the range of the CIDR Results from 10,000 IP address, with 2 static, 9,998 random. MacBook:cidr Xeon$ /usr/local/php5/bin/php index.php | grep Pass: IP: 216.21.215.10 Pass: In the range of the CIDR IP: 192.168.0.1 Pass: In the range of the CIDR IP: 192.168.18.45 Pass: In the range of the CIDR Results from 100,000 IP address, with 2 static, 99,998 random. (After 3rd run) MacBook:cidr Xeon$ /usr/local/php5/bin/php index.php | grep Pass: IP: 216.21.215.10 Pass: In the range of the CIDR IP: 192.168.0.1 Pass: In the range of the CIDR IP: 192.168.26.138 Pass: In the range of the CIDR IP: 192.168.189.88 Pass: In the range of the CIDR */ function RandIPAddress() { $randIP = ""; for ($i = 0; $i <= 3; $i++) { if ($i > 0) { $randIP .= "."; } $randIP .= rand(0, 255); } return $randIP; }