Code:
<?php
// I use some dirty constructs in the building of the benchtable, so ignore notices :P
error_reporting(E_ALL ^ E_NOTICE);
//*
// This seems to be overall the fastest way to do IPv4 checking in PHP
function validateIPv4($IP)
{
return preg_match('/^(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/', $IP);
}
// This is a single regexp-approach based on rfc3986 that actually passes all of my testcases, it is reasonably performant
function validateIPv6_1($IP)
{
return preg_match('/^
(?:
(?:
(?:[a-f0-9]{1,4}:){6}
|
::(?:[a-f0-9]{1,4}:){0,4}
|
(?:[a-f0-9]{1,4}:){1,1}:(?:[a-f0-9]{1,4}:){4}
|
(?:[a-f0-9]{1,4}:){1,2}:(?:[a-f0-9]{1,4}:){3}
|
(?:[a-f0-9]{1,4}:){1,3}:(?:[a-f0-9]{1,4}:){2}
|
(?:[a-f0-9]{1,4}:){1,4}:(?:[a-f0-9]{1,4}:){1}
|
(?:[a-f0-9]{1,4}:){1,5}:
)
(?:
[a-f0-9]{1,4}:[a-f0-9]{1,4}
|
(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
)
|
(?::|(?:[a-f0-9]{1,4}:){1,6}):(?:[a-f0-9]{1,4})?
)
$/ix',
$IP
);
}
function validateIPv6_2($IP)
{
if (strlen($IP) < 3)
{
return ( $IP == '::' ? true : false ) ;
}
if (strpos($IP, '.'))
{
$lastcolon = strrpos($IP, ':');
if (!($lastcolon && validateIPv4(substr($IP, $lastcolon + 1))))
{
return false;
}
$IP = substr($IP, 0, $lastcolon) . ':0:0';
$colonCount = substr_count($IP, ':');
if ( $colonCount > 6 )
{
return false;
}
}
else
{
$colonCount = substr_count($IP, ':');
}
if (strpos($IP, '::') === false)
{
return ( preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $IP) ? true : false ) ;
}
if ( $colonCount > 8 )
{
return false;
}
if ($colonCount < 8)
{
return ( preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $IP) ? true : false ) ;
}
// special case with ending or starting double colon
if ($colonCount == 8)
{
return ( preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $IP) ? true : false ) ;
}
return false;
}
// This is a single regexp-approach based on rfc3986 that actually passes all of my testcases, it is reasonably performant
function validateIPv6_3($IP)
{
if (strlen($IP) < 3)
{
return ( $IP == '::' ? true : false ) ;
}
if ( preg_match('/^
(?:
(?:
(?:[a-f0-9]{1,4}:){6}
|
::(?:[a-f0-9]{1,4}:){0,4}
|
(?:[a-f0-9]{1,4}:){1,1}:(?:[a-f0-9]{1,4}:){4}
|
(?:[a-f0-9]{1,4}:){1,2}:(?:[a-f0-9]{1,4}:){3}
|
(?:[a-f0-9]{1,4}:){1,3}:(?:[a-f0-9]{1,4}:){2}
|
(?:[a-f0-9]{1,4}:){1,4}:(?:[a-f0-9]{1,4}:){1}
|
(?:[a-f0-9]{1,4}:){1,5}:
)
(?:
[a-f0-9]{1,4}:[a-f0-9]{1,4}
|
(?:(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
)
|
(?::|(?:[a-f0-9]{1,4}:){1,6}):(?:[a-f0-9]{1,4})?
)
$/ix',
$IP
) )
{
$index = strrpos( $IP, '::' );
$groupCount = substr_count($IP, ':');
if ( strpos($IP, '.') !== false )
{
if ( $index === 0 )
{
return true;
}
$groupMax = 6;
}
else
{
$groupMax = 7;
}
/*
if ( $index !== false && $index > 0 )
{
$groupMax--;
}
*/
if ( $index !== false )
{
$groupMax = ( $index === 0 || $index === ( strlen( $IP ) - 2 ) ) ? $groupMax : $groupMax - 1;
}
//echo "$IP = $groupMax * $groupCount\n";
if ( $groupCount > $groupMax )
{
return false; // Too many IPv6 groups in address
}
return true;
}
else
{
return false;
}
}
// This is a single regexp-approach based on rfc3986 that actually passes all of my testcases, it is reasonably performant
function validateIPv6_4($IP)
{
if (strlen($IP) < 3)
{
return ( $IP == '::' ? true : false ) ;
}
if ( ! preg_match('/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/', $IP
) )
{
return false;
}
else
{
return true;
}
}
function validateIPv6_5($IP)
{
return ( filter_var( trim( $IP ), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false ? false : true );
}
// testcases; a value of true means it is a valid IPv6 address, false means it is invalid
$unitTests = array(
'' => false,
'2001:0000:1234:0000:0000:C1C0:ABCD:0876' => true,
'3ffe:0b00:0000:0000:0001:0000:0000:000a' => true,
'FF02:0000:0000:0000:0000:0000:0000:0001' => true,
'0000:0000:0000:0000:0000:0000:0000:0001' => true,
'0000:0000:0000:0000:0000:0000:0000:0000' => true,
'::ffff:192.168.1.26' => true,
'02001:0000:1234:0000:0000:C1C0:ABCD:0876' => false, # extra 0 not allowed!
'2001:0000:1234:0000:00001:C1C0:ABCD:0876' => false, # extra 0 not allowed!
' 2001:0000:1234:0000:0000:C1C0:ABCD:0876' => true, # leading space
'2001:0000:1234:0000:0000:C1C0:ABCD:0876' => true, # trailing space
' 2001:0000:1234:0000:0000:C1C0:ABCD:0876 ' => true, # leading and trailing space
' 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0' => false, # junk after valid address
'2001:0000:1234: 0000:0000:C1C0:ABCD:0876' => false, # internal space
'2001:1:1:1:1:1:255Z255X255Y255' => false, # garbage instead of "." in IPv4
'::ffff:192x168.1.26' => false,
'3ffe:0b00:0000:0001:0000:0000:000a' => false, # seven segments
'FF02:0000:0000:0000:0000:0000:0000:0000:0001' => false, # nine segments
'3ffe:b00::1::a' => false, # double "::"
'::1111:2222:3333:4444:5555:6666::' => false, # double "::"
'2::10' => true,
'ff02::1' => true,
'fe80::' => true,
'2002::' => true,
'2001:db8::' => true,
'2001:0db8:1234::' => true,
'::ffff:0:0' => true,
'::1' => true,
'::ffff:192.168.1.1' => true,
'1:2:3:4:5:6:7:8' => true,
'1:2:3:4:5:6::8' => true,
'1:2:3:4:5::8' => true,
'1:2:3:4::8' => true,
'1:2:3::8' => true,
'1:2::8' => true,
'1::8' => true,
'1::2:3:4:5:6:7' => true,
'1::2:3:4:5:6' => true,
'1::2:3:4:5' => true,
'1::2:3:4' => true,
'1::2:3' => true,
'1::8' => true,
'::2:3:4:5:6:7:8' => true,
'::2:3:4:5:6:7' => true,
'::2:3:4:5:6' => true,
'::2:3:4:5' => true,
'::2:3:4' => true,
'::2:3' => true,
'::8' => true,
'1:2:3:4:5:6::' => true,
'1:2:3:4:5::' => true,
'1:2:3:4::' => true,
'1:2:3::' => true,
'1:2::' => true,
'1::' => true,
'1:2:3:4:5::7:8' => true,
'1:2:3::4:5::7:8' => false, # Double "::"
'12345::6:7:8' => false,
'1:2:3:4::7:8' => true,
'1:2:3::7:8' => true,
'1:2::7:8' => true,
'1::7:8' => true,
'1:2:3:4:5:6:1.2.3.4' => true,
'1:2:3:4:5::1.2.3.4' => true,
'1:2:3:4::1.2.3.4' => true,
'1:2:3::1.2.3.4' => true,
'1:2::1.2.3.4' => true,
'1::1.2.3.4' => true,
'1:2:3:4::5:1.2.3.4' => true,
'1:2:3::5:1.2.3.4' => true,
'1:2::5:1.2.3.4' => true,
'1::5:1.2.3.4' => true,
'1::5:11.22.33.44' => true,
'1::5:400.2.3.4' => false,
'1::5:260.2.3.4' => false,
'1::5:256.2.3.4' => false,
'1::5:1.256.3.4' => false,
'1::5:1.2.256.4' => false,
'1::5:1.2.3.256' => false,
'1::5:300.2.3.4' => false,
'1::5:1.300.3.4' => false,
'1::5:1.2.300.4' => false,
'1::5:1.2.3.300' => false,
'1::5:900.2.3.4' => false,
'1::5:1.900.3.4' => false,
'1::5:1.2.900.4' => false,
'1::5:1.2.3.900' => false,
'1::5:300.300.300.300' => false,
'1::5:3000.30.30.30' => false,
'1::400.2.3.4' => false,
'1::260.2.3.4' => false,
'1::256.2.3.4' => false,
'1::1.256.3.4' => false,
'1::1.2.256.4' => false,
'1::1.2.3.256' => false,
'1::300.2.3.4' => false,
'1::1.300.3.4' => false,
'1::1.2.300.4' => false,
'1::1.2.3.300' => false,
'1::900.2.3.4' => false,
'1::1.900.3.4' => false,
'1::1.2.900.4' => false,
'1::1.2.3.900' => false,
'1::300.300.300.300' => false,
'1::3000.30.30.30' => false,
'::400.2.3.4' => false,
'::260.2.3.4' => false,
'::256.2.3.4' => false,
'::1.256.3.4' => false,
'::1.2.256.4' => false,
'::1.2.3.256' => false,
'::300.2.3.4' => false,
'::1.300.3.4' => false,
'::1.2.300.4' => false,
'::1.2.3.300' => false,
'::900.2.3.4' => false,
'::1.900.3.4' => false,
'::1.2.900.4' => false,
'::1.2.3.900' => false,
'::300.300.300.300' => false,
'::3000.30.30.30' => false,
'fe80::217:f2ff:254.7.237.98' => true,
'fe80::217:f2ff:fe07:ed62' => true,
'2001:DB8:0:0:8:800:200C:417A' => true,# unicast, full
'FF01:0:0:0:0:0:0:101' => true,# multicast, full
'0:0:0:0:0:0:0:1' => true,# loopback, full
'0:0:0:0:0:0:0:0' => true,# unspecified, full
'2001:DB8::8:800:200C:417A' => true,# unicast, compressed
'FF01::101' => true,# multicast, compressed
'::1' => true,# loopback, compressed, non-routable
'::' => true,# unspecified, compressed, non-routable
'0:0:0:0:0:0:13.1.68.3' => true,# IPv4-compatible IPv6 address, full, deprecated
'0:0:0:0:0:FFFF:129.144.52.38' => true,# IPv4-mapped IPv6 address, full
'::13.1.68.3' => true,# IPv4-compatible IPv6 address, compressed, deprecated
'::FFFF:129.144.52.38' => true,# IPv4-mapped IPv6 address, compressed
'2001:DB8:0:0:8:800:200C:417A:221' => false,# unicast, full
'FF01::101::2' => false,# multicast, compressed
'' => false,# nothing
'fe80:0000:0000:0000:0204:61ff:fe9d:f156' => true,
'fe80:0:0:0:204:61ff:fe9d:f156' => true,
'fe80::204:61ff:fe9d:f156' => true,
'fe80:0000:0000:0000:0204:61ff:254.157.241.086' => false,
'fe80:0:0:0:204:61ff:254.157.241.86' => true,
'fe80::204:61ff:254.157.241.86' => true,
'::1' => true,
'fe80::' => true,
'fe80::1' => true,
':' => false,
'1111:2222:3333:4444::5555:' => false,
'1111:2222:3333::5555:' => false,
'1111:2222::5555:' => false,
'1111::5555:' => false,
'::5555:' => false,
':::' => false,
'1111:' => false,
':' => false,
':1111:2222:3333:4444::5555' => false,
':1111:2222:3333::5555' => false,
':1111:2222::5555' => false,
':1111::5555' => false,
':::5555' => false,
':::' => false,
'1.2.3.4:1111:2222:3333:4444::5555' => false,
'1.2.3.4:1111:2222:3333::5555' => false,
'1.2.3.4:1111:2222::5555' => false,
'1.2.3.4:1111::5555' => false,
'1.2.3.4::5555' => false,
'1.2.3.4::' => false,
'2001:0db8:85a3:0000:0000:8a2e:0370:7334' => true,
'2001:db8:85a3:0:0:8a2e:370:7334' => true,
'2001:db8:85a3::8a2e:370:7334' => true,
'2001:0db8:0000:0000:0000:0000:1428:57ab' => true,
'2001:0db8:0000:0000:0000::1428:57ab' => true,
'2001:0db8:0:0:0:0:1428:57ab' => true,
'2001:0db8:0:0::1428:57ab' => true,
'2001:0db8::1428:57ab' => true,
'2001:db8::1428:57ab' => true,
'0000:0000:0000:0000:0000:0000:0000:0001' => true,
'::1' => true,
'::ffff:12.34.56.78' => true,
'::ffff:0c22:384e' => true,
'2001:0db8:1234:0000:0000:0000:0000:0000' => true,
'2001:0db8:1234:ffff:ffff:ffff:ffff:ffff' => true,
'2001:db8:a::123' => true,
'fe80::' => true,
'::ffff:192.0.2.128' => true,
'::ffff:c000:280' => true,
'123' => false,
'ldkfj' => false,
'2001::FFD3::57ab' => false,
'2001:db8:85a3::8a2e:37023:7334' => false,
'2001:db8:85a3::8a2e:370k:7334' => false,
'1:2:3:4:5:6:7:8:9' => false,
'1::2::3' => false,
'1:::3:4:5' => false,
'1:2:3::4:5:6:7:8:9' => false,
'::ffff:2.3.4' => false,
'::ffff:257.1.2.3' => false,
'1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:7777:8888' => true,
'1111:2222:3333:4444:5555:6666:7777::' => true,
'1111:2222:3333:4444:5555:6666::' => true,
'1111:2222:3333:4444:5555::' => true,
'1111:2222:3333:4444::' => true,
'1111:2222:3333::' => true,
'1111:2222::' => true,
'1111::' => true,
'::' => true,
'1111:2222:3333:4444:5555:6666::8888' => true,
'1111:2222:3333:4444:5555::8888' => true,
'1111:2222:3333:4444::8888' => true,
'1111:2222:3333::8888' => true,
'1111:2222::8888' => true,
'1111::8888' => true,
'::8888' => true,
'1111:2222:3333:4444:5555::7777:8888' => true,
'1111:2222:3333:4444::7777:8888' => true,
'1111:2222:3333::7777:8888' => true,
'1111:2222::7777:8888' => true,
'1111::7777:8888' => true,
'::7777:8888' => true,
'1111:2222:3333:4444::6666:7777:8888' => true,
'1111:2222:3333::6666:7777:8888' => true,
'1111:2222::6666:7777:8888' => true,
'1111::6666:7777:8888' => true,
'::6666:7777:8888' => true,
'1111:2222:3333::5555:6666:7777:8888' => true,
'1111:2222::5555:6666:7777:8888' => true,
'1111::5555:6666:7777:8888' => true,
'::5555:6666:7777:8888' => true,
'1111:2222::4444:5555:6666:7777:8888' => true,
'1111::4444:5555:6666:7777:8888' => true,
'::4444:5555:6666:7777:8888' => true,
'1111::3333:4444:5555:6666:7777:8888' => true,
'::3333:4444:5555:6666:7777:8888' => true,
'::2222:3333:4444:5555:6666:7777:8888' => true,
'1111:2222:3333:4444:5555:6666:123.123.123.123' => true,
'1111:2222:3333:4444:5555::123.123.123.123' => true,
'1111:2222:3333:4444::123.123.123.123' => true,
'1111:2222:3333::123.123.123.123' => true,
'1111:2222::123.123.123.123' => true,
'1111::123.123.123.123' => true,
'::123.123.123.123' => true,
'1111:2222:3333:4444::6666:123.123.123.123' => true,
'1111:2222:3333::6666:123.123.123.123' => true,
'1111:2222::6666:123.123.123.123' => true,
'1111::6666:123.123.123.123' => true,
'::6666:123.123.123.123' => true,
'1111:2222:3333::5555:6666:123.123.123.123' => true,
'1111:2222::5555:6666:123.123.123.123' => true,
'1111::5555:6666:123.123.123.123' => true,
'::5555:6666:123.123.123.123' => true,
'1111:2222::4444:5555:6666:123.123.123.123' => true,
'1111::4444:5555:6666:123.123.123.123' => true,
'::4444:5555:6666:123.123.123.123' => true,
'1111::3333:4444:5555:6666:123.123.123.123' => true,
'::2222:3333:4444:5555:6666:123.123.123.123' => true,
'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX' => false,
'1111:2222:3333:4444:5555:6666:7777:8888:9999' => false,
'1111:2222:3333:4444:5555:6666:7777:8888::' => false,
'::2222:3333:4444:5555:6666:7777:8888:9999' => false,
'1111:2222:3333:4444:5555:6666:7777' => false,
'1111:2222:3333:4444:5555:6666' => false,
'1111:2222:3333:4444:5555' => false,
'1111:2222:3333:4444' => false,
'1111:2222:3333' => false,
'1111:2222' => false,
'1111' => false,
'11112222:3333:4444:5555:6666:7777:8888' => false,
'1111:22223333:4444:5555:6666:7777:8888' => false,
'1111:2222:33334444:5555:6666:7777:8888' => false,
'1111:2222:3333:44445555:6666:7777:8888' => false,
'1111:2222:3333:4444:55556666:7777:8888' => false,
'1111:2222:3333:4444:5555:66667777:8888' => false,
'1111:2222:3333:4444:5555:6666:77778888' => false,
'1111:2222:3333:4444:5555:6666:7777:8888:' => false,
'1111:2222:3333:4444:5555:6666:7777:' => false,
'1111:2222:3333:4444:5555:6666:' => false,
'1111:2222:3333:4444:5555:' => false,
'1111:2222:3333:4444:' => false,
'1111:2222:3333:' => false,
'1111:2222:' => false,
'1111:' => false,
':' => false,
':8888' => false,
':7777:8888' => false,
':6666:7777:8888' => false,
':5555:6666:7777:8888' => false,
':4444:5555:6666:7777:8888' => false,
':3333:4444:5555:6666:7777:8888' => false,
':2222:3333:4444:5555:6666:7777:8888' => false,
':1111:2222:3333:4444:5555:6666:7777:8888' => false,
':::2222:3333:4444:5555:6666:7777:8888' => false,
'1111:::3333:4444:5555:6666:7777:8888' => false,
'1111:2222:::4444:5555:6666:7777:8888' => false,
'1111:2222:3333:::5555:6666:7777:8888' => false,
'1111:2222:3333:4444:::6666:7777:8888' => false,
'1111:2222:3333:4444:5555:::7777:8888' => false,
'1111:2222:3333:4444:5555:6666:::8888' => false,
'1111:2222:3333:4444:5555:6666:7777:::' => false,
'::2222::4444:5555:6666:7777:8888' => false,
'::2222:3333::5555:6666:7777:8888' => false,
'::2222:3333:4444::6666:7777:8888' => false,
'::2222:3333:4444:5555::7777:8888' => false,
'::2222:3333:4444:5555:7777::8888' => false,
'::2222:3333:4444:5555:7777:8888::' => false,
'1111::3333::5555:6666:7777:8888' => false,
'1111::3333:4444::6666:7777:8888' => false,
'1111::3333:4444:5555::7777:8888' => false,
'1111::3333:4444:5555:6666::8888' => false,
'1111::3333:4444:5555:6666:7777::' => false,
'1111:2222::4444::6666:7777:8888' => false,
'1111:2222::4444:5555::7777:8888' => false,
'1111:2222::4444:5555:6666::8888' => false,
'1111:2222::4444:5555:6666:7777::' => false,
'1111:2222:3333::5555::7777:8888' => false,
'1111:2222:3333::5555:6666::8888' => false,
'1111:2222:3333::5555:6666:7777::' => false,
'1111:2222:3333:4444::6666::8888' => false,
'1111:2222:3333:4444::6666:7777::' => false,
'1111:2222:3333:4444:5555::7777::' => false,
'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:00.00.00.00' => false,
'1111:2222:3333:4444:5555:6666:000.000.000.000' => false,
'1111:2222:3333:4444:5555:6666:256.256.256.256' => false,
'1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:7777:1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666::1.2.3.4' => false,
'::2222:3333:4444:5555:6666:7777:1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:1.2.3.4.5' => false,
'1111:2222:3333:4444:5555:1.2.3.4' => false,
'1111:2222:3333:4444:1.2.3.4' => false,
'1111:2222:3333:1.2.3.4' => false,
'1111:2222:1.2.3.4' => false,
'1111:1.2.3.4' => false,
'1.2.3.4' => false,
'11112222:3333:4444:5555:6666:1.2.3.4' => false,
'1111:22223333:4444:5555:6666:1.2.3.4' => false,
'1111:2222:33334444:5555:6666:1.2.3.4' => false,
'1111:2222:3333:44445555:6666:1.2.3.4' => false,
'1111:2222:3333:4444:55556666:1.2.3.4' => false,
'1111:2222:3333:4444:5555:66661.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:255255.255.255' => false,
'1111:2222:3333:4444:5555:6666:255.255255.255' => false,
'1111:2222:3333:4444:5555:6666:255.255.255255' => false,
':1.2.3.4' => false,
':6666:1.2.3.4' => false,
':5555:6666:1.2.3.4' => false,
':4444:5555:6666:1.2.3.4' => false,
':3333:4444:5555:6666:1.2.3.4' => false,
':2222:3333:4444:5555:6666:1.2.3.4' => false,
':1111:2222:3333:4444:5555:6666:1.2.3.4' => false,
':::2222:3333:4444:5555:6666:1.2.3.4' => false,
'1111:::3333:4444:5555:6666:1.2.3.4' => false,
'1111:2222:::4444:5555:6666:1.2.3.4' => false,
'1111:2222:3333:::5555:6666:1.2.3.4' => false,
'1111:2222:3333:4444:::6666:1.2.3.4' => false,
'1111:2222:3333:4444:5555:::1.2.3.4' => false,
'::2222::4444:5555:6666:1.2.3.4' => false,
'::2222:3333::5555:6666:1.2.3.4' => false,
'::2222:3333:4444::6666:1.2.3.4' => false,
'::2222:3333:4444:5555::1.2.3.4' => false,
'1111::3333::5555:6666:1.2.3.4' => false,
'1111::3333:4444::6666:1.2.3.4' => false,
'1111::3333:4444:5555::1.2.3.4' => false,
'1111:2222::4444::6666:1.2.3.4' => false,
'1111:2222::4444:5555::1.2.3.4' => false,
'1111:2222:3333::5555::1.2.3.4' => false,
'::.' => false,
'::..' => false,
'::...' => false,
'::1...' => false,
'::1.2..' => false,
'::1.2.3.' => false,
'::.2..' => false,
'::.2.3.' => false,
'::.2.3.4' => false,
'::..3.' => false,
'::..3.4' => false,
'::...4' => false,
':1111:2222:3333:4444:5555:6666:7777::' => false,
':1111:2222:3333:4444:5555:6666::' => false,
':1111:2222:3333:4444:5555::' => false,
':1111:2222:3333:4444::' => false,
':1111:2222:3333::' => false,
':1111:2222::' => false,
':1111::' => false,
':::' => false,
':1111:2222:3333:4444:5555:6666::8888' => false,
':1111:2222:3333:4444:5555::8888' => false,
':1111:2222:3333:4444::8888' => false,
':1111:2222:3333::8888' => false,
':1111:2222::8888' => false,
':1111::8888' => false,
':::8888' => false,
':1111:2222:3333:4444:5555::7777:8888' => false,
':1111:2222:3333:4444::7777:8888' => false,
':1111:2222:3333::7777:8888' => false,
':1111:2222::7777:8888' => false,
':1111::7777:8888' => false,
':::7777:8888' => false,
':1111:2222:3333:4444::6666:7777:8888' => false,
':1111:2222:3333::6666:7777:8888' => false,
':1111:2222::6666:7777:8888' => false,
':1111::6666:7777:8888' => false,
':::6666:7777:8888' => false,
':1111:2222:3333::5555:6666:7777:8888' => false,
':1111:2222::5555:6666:7777:8888' => false,
':1111::5555:6666:7777:8888' => false,
':::5555:6666:7777:8888' => false,
':1111:2222::4444:5555:6666:7777:8888' => false,
':1111::4444:5555:6666:7777:8888' => false,
':::4444:5555:6666:7777:8888' => false,
':1111::3333:4444:5555:6666:7777:8888' => false,
':::3333:4444:5555:6666:7777:8888' => false,
':::2222:3333:4444:5555:6666:7777:8888' => false,
':1111:2222:3333:4444:5555:6666:1.2.3.4' => false,
':1111:2222:3333:4444:5555::1.2.3.4' => false,
':1111:2222:3333:4444::1.2.3.4' => false,
':1111:2222:3333::1.2.3.4' => false,
':1111:2222::1.2.3.4' => false,
':1111::1.2.3.4' => false,
':::1.2.3.4' => false,
':1111:2222:3333:4444::6666:1.2.3.4' => false,
':1111:2222:3333::6666:1.2.3.4' => false,
':1111:2222::6666:1.2.3.4' => false,
':1111::6666:1.2.3.4' => false,
':::6666:1.2.3.4' => false,
':1111:2222:3333::5555:6666:1.2.3.4' => false,
':1111:2222::5555:6666:1.2.3.4' => false,
':1111::5555:6666:1.2.3.4' => false,
':::5555:6666:1.2.3.4' => false,
':1111:2222::4444:5555:6666:1.2.3.4' => false,
':1111::4444:5555:6666:1.2.3.4' => false,
':::4444:5555:6666:1.2.3.4' => false,
':1111::3333:4444:5555:6666:1.2.3.4' => false,
':::2222:3333:4444:5555:6666:1.2.3.4' => false,
'1111:2222:3333:4444:5555:6666:7777:::' => false,
'1111:2222:3333:4444:5555:6666:::' => false,
'1111:2222:3333:4444:5555:::' => false,
'1111:2222:3333:4444:::' => false,
'1111:2222:3333:::' => false,
'1111:2222:::' => false,
'1111:::' => false,
':::' => false,
'1111:2222:3333:4444:5555:6666::8888:' => false,
'1111:2222:3333:4444:5555::8888:' => false,
'1111:2222:3333:4444::8888:' => false,
'1111:2222:3333::8888:' => false,
'1111:2222::8888:' => false,
'1111::8888:' => false,
'::8888:' => false,
'1111:2222:3333:4444:5555::7777:8888:' => false,
'1111:2222:3333:4444::7777:8888:' => false,
'1111:2222:3333::7777:8888:' => false,
'1111:2222::7777:8888:' => false,
'1111::7777:8888:' => false,
'::7777:8888:' => false,
'1111:2222:3333:4444::6666:7777:8888:' => false,
'1111:2222:3333::6666:7777:8888:' => false,
'1111:2222::6666:7777:8888:' => false,
'1111::6666:7777:8888:' => false,
'::6666:7777:8888:' => false,
'1111:2222:3333::5555:6666:7777:8888:' => false,
'1111:2222::5555:6666:7777:8888:' => false,
'1111::5555:6666:7777:8888:' => false,
'::5555:6666:7777:8888:' => false,
'1111:2222::4444:5555:6666:7777:8888:' => false,
'1111::4444:5555:6666:7777:8888:' => false,
'::4444:5555:6666:7777:8888:' => false,
'1111::3333:4444:5555:6666:7777:8888:' => false,
'::3333:4444:5555:6666:7777:8888:' => false,
'::2222:3333:4444:5555:6666:7777:8888:' => false,
);
$benchmarks = array();
$iterations = 100;
$numfunctions = 5;
foreach ($unitTests as $ip => $assertion)
{
$benchmarks[$ip] = array();
for ($i = 1; $i <= $numfunctions; $i++)
{
$j = $iterations;
$f = 'validateIPv6_' . $i;
$s = microtime(true);
while ($j--)
{
$f($ip);
}
$e = microtime(true);
$benchmarks[$ip][$i] = $e - $s;
}
}
// print table
echo '<table border=1><tr>';
for ($i = 0; $i <= $numfunctions; $i++)
{
echo '<td>' . ($i ? 'validateIPv6_' . $i : ' ') . '</td>';
}
echo '</tr>';
$totals = array(
'valid' => array(),
'invalid' => array(),
'grand' => array()
);
foreach ($unitTests as $ip => $assertion)
{
echo '<tr><td style="color:' . ($assertion ? 'green' : 'red') . '">' . ($ip ? $ip : ' ') . '</td>';
for ($i = 1; $i <= $numfunctions; $i++)
{
$f = 'validateIPv6_' . $i;
$result = $f($ip);
$min = min($benchmarks[$ip]);
$correct = (bool)$result == $assertion;
$totals['grand'][$i] += $benchmarks[$ip][$i];
if ($assertion)
$totals['valid'][$i] += $benchmarks[$ip][$i];
else
$totals['invalid'][$i] += $benchmarks[$ip][$i];
echo '<td style="text-align:right' . ($correct ? '' : ';color:red') . ($benchmarks[$ip][$i] == $min ? ';background:lime' : '') . '">' . number_format($benchmarks[$ip][$i], 3, '.', '') . '</td>';
}
echo '</tr>';
}
foreach ($totals as $label => $results)
{
echo '<tr><td><b>' . $label . '</td>';
for ($i = 1; $i <= $numfunctions; $i++)
{
$min = min($results);
echo '<td style="text-align:right' . ($results[$i] == $min ? ';background:lime' : '') . '">' . number_format($results[$i], 3, '.', '') . '</td>';
}
echo '</tr>';
}
echo '</table>';
?>
Commentaar bij functies klopt overigens niet altijd, maar ik had geen zin omdat aan te passen.