Skip to content

Instantly share code, notes, and snippets.

@ezzatron
Last active December 28, 2015 09:59
Show Gist options
  • Save ezzatron/7482461 to your computer and use it in GitHub Desktop.
Save ezzatron/7482461 to your computer and use it in GitHub Desktop.
PHP IPv4 validation profiling
<?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');
$ 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