Last active
December 28, 2015 09:59
-
-
Save ezzatron/7482461 to your computer and use it in GitHub Desktop.
PHP IPv4 validation profiling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function ipv4AddressData() | |
{ | |
// address isValid | |
return array( | |
'Single digit 0' => array('0.0.0.0', true), | |
'Single digit 1' => array('1.1.1.1', true), | |
'Single digit 9' => array('9.9.9.9', true), | |
'Double digit 10' => array('10.10.10.10', true), | |
'Double digit 99' => array('99.99.99.99', true), | |
'Triple digit 100' => array('100.100.100.100', true), | |
'Triple digit 199' => array('199.199.199.199', true), | |
'Triple digit 200' => array('200.200.200.200', true), | |
'Triple digit 249' => array('249.249.249.249', true), | |
'Triple digit 255' => array('255.255.255.255', true), | |
'Invalid - 256' => array('256.256.256.256', false), | |
'Invalid - too few octets' => array('1.1.1', false), | |
'Invalid - too many octets' => array('1.1.1.1.1', false), | |
'Invalid - non-integer' => array('foo.bar.baz.qux', false), | |
'Invalid - IPv6' => array('[0:0:0:0:0:0:0:1]', false), | |
'Invalid - dotted hexadecimal' => array('0xC0.0x00.0x02.0xEB', false), | |
'Invalid - dotted octal' => array('0300.0000.0002.0353', false), | |
'Invalid - dotted binary' => array('01111111.00000000.00000000.00000001', false), | |
'Invalid - hexadecimal' => array('0xC00002EB', false), | |
'Invalid - decimal' => array('3221226219', false), | |
'Invalid - octal' => array('030000001353', false), | |
); | |
} | |
function doTest($name) | |
{ | |
$failures = 0; | |
$startTime = microtime(true); | |
for ($i = 0; $i < 100000; ++$i) { | |
foreach (ipv4AddressData() as $tuple) { | |
if ($name($tuple[0]) !== $tuple[1]) { | |
++$failures; | |
} | |
} | |
} | |
printf( | |
"%s had %d failures, and completed in %0.2f seconds\n", | |
$name, | |
$failures, | |
microtime(true) - $startTime | |
); | |
} | |
function filters($address) | |
{ | |
return false !== filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); | |
} | |
function regex25Last($address) | |
{ | |
return true && preg_match('/^(?:(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/', $address); | |
} | |
function regex25First($address) | |
{ | |
return true && preg_match('/^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)$/', $address); | |
} | |
function regexHybrid($address) | |
{ | |
return preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $address, $matches) && | |
intval($matches[1] < 256) && | |
intval($matches[2] < 256) && | |
intval($matches[3] < 256) && | |
intval($matches[4] < 256); | |
} | |
function explodeNoLoopCtypeFirst($address) | |
{ | |
$octets = explode('.', $address); | |
if (4 !== count($octets)) { | |
return false; | |
} | |
return ctype_digit($octets[0]) && | |
ctype_digit($octets[1]) && | |
ctype_digit($octets[2]) && | |
ctype_digit($octets[3]) && | |
intval($octets[0]) < 256 && | |
intval($octets[1]) < 256 && | |
intval($octets[2]) < 256 && | |
intval($octets[3]) < 256; | |
} | |
function explodeNoLoopIntvalFirst($address) | |
{ | |
$octets = explode('.', $address); | |
if (4 !== count($octets)) { | |
return false; | |
} | |
return intval($octets[0]) < 256 && | |
intval($octets[1]) < 256 && | |
intval($octets[2]) < 256 && | |
intval($octets[3]) < 256 && | |
ctype_digit($octets[0]) && | |
ctype_digit($octets[1]) && | |
ctype_digit($octets[2]) && | |
ctype_digit($octets[3]); | |
} | |
function explodeWithLoopCountFirst($address) | |
{ | |
$octets = explode('.', $address); | |
if (4 !== count($octets)) { | |
return false; | |
} | |
foreach ($octets as $octet) { | |
if (!ctype_digit($octet) || intval($octet) > 255) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function explodeWithLoopCountAfter($address) | |
{ | |
$count = 0; | |
foreach (explode('.', $address) as $octet) { | |
if (!ctype_digit($octet) || intval($octet) > 255) { | |
return false; | |
} | |
++$count; | |
} | |
return 4 === $count; | |
} | |
doTest('filters'); | |
doTest('regex25Last'); | |
doTest('regex25First'); | |
doTest('regexHybrid'); | |
doTest('explodeNoLoopCtypeFirst'); | |
doTest('explodeNoLoopIntvalFirst'); | |
doTest('explodeWithLoopCountFirst'); | |
doTest('explodeWithLoopCountAfter'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ php -dxdebug.remote_autostart=0 -dxdebug.remote_enable=0 -dxdebug.profiler_enable=0 ipv4Validation.php | |
filters had 0 failures, and completed in 4.15 seconds | |
regex25Last had 0 failures, and completed in 4.99 seconds | |
regex25First had 0 failures, and completed in 5.17 seconds | |
regexHybrid had 0 failures, and completed in 8.59 seconds | |
explodeNoLoopCtypeFirst had 0 failures, and completed in 13.03 seconds | |
explodeNoLoopIntvalFirst had 0 failures, and completed in 13.08 seconds | |
explodeWithLoopCountFirst had 0 failures, and completed in 12.91 seconds | |
explodeWithLoopCountAfter had 0 failures, and completed in 13.30 seconds | |
Hardware: | |
Model Name: MacBook Pro | |
Model Identifier: MacBookPro11,3 | |
Processor Name: Intel Core i7 | |
Processor Speed: 2.3 GHz | |
Number of Processors: 1 | |
Total Number of Cores: 4 | |
L2 Cache (per Core): 256 KB | |
L3 Cache: 6 MB | |
Memory: 16 GB |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment