PDA

Bekijk Volledige Versie : Geldig IPv6 formaat



SebastiaanStok
17/05/10, 10:45
Ik ben nog niet zo thuis in het IPv6 gebeuren, maar weet net de basis dingen :)

Ik ben nu bezig met een invoer validatie die controleert of iets een geldig IPv6 adres is. Alleen heb ik nu meer dan 12 verschillende versies geprobeerd, en alle allemaal doen ze iets anders :mad:

Nu ben ik uit gegaan van de testcases die de beschikbaar zijn, maar volgens mij staan daar ook een paar fouten tussen...

http://www.faqs.org/rfcs/rfc4291.html

Ik weet dat een IPv6 moet bestaan uit 8 groepen van 4 HEX decimalen.
Dat voorgaande nullen mogen worden weggelaten, en dat achtereen volgende groepen van alleen nullen mogen worden veranderd in :: (0:0:0 -> :: ), en dat dit maar één keer mag.

Een IPv4 mag worden embedded, er mogen dan maximaal 6 groepen zijn.

Als je compressie toepast veranderd het maximaal aantal groepen (ja maar hoe)?

Volgens de testcases zijn deze geldig.



2001:0db8:0000:0000:0000:0000:1428:57ab
2001:0DB8:0000:0000:0000:0000:1428:57AB
2001:db8::1428:57ab
::
::1
::1.2.3.4
a:b:c::1.2.3.4
a:b:c:d::1.2.3.4
a:b:c:d:e::1.2.3.4
a:b:c:d:e:f:1.2.3.4
a:b:c:d:e:f:0:1
a::c:d:e:f:0:1
a::d:e:f:0:1
a::e:f:0:1
a::f:0:1
a::0:1
a::1
a::
::a:b:c:d:e:f
::b:c:d:e:f
::c:d:e:f
::d:e:f
::e:f
::f
a:b:c:d:e:f::
b:c:d:e:f::
c:d:e:f::
d:e:f::
e:f::
f::
a:b:c:d:e:f::0


En zijn deze ongeldig.



1111:2222:3333::4444:5555:12.34.56.78
1111:2222:3333::4444:5555:6666:7777
2001:00db8:0000:0000:0000:0000:1428:57ab
2001:0db8:xxxx:0000:0000:0000:1428:57ab
2001:db8::1428::57ab
2001:dx0::1234
2001:db0::12345
:
:::
::::
:::1
::256.0.0.1
::01.02.03.04
a:b:c:d:e:f:1.256.3.4
a:b:c:d:e:f::1.2.3.4
a:b:c:d:e:f:0:1:2
a::b:c:d:e:f:0:1
::0:1:a:b:c:d:e:f
::0:a:b:c:d:e:f
0:1:a:b:c:d:e:f::
0:a:b:c:d:e:f::
a:b:::e:f
::a:
::a::
:a::b
a::b:
::a:b::c
abcde::f
10.0.0.1
:10.0.0.1
0:0:0:255.255.255.255
1fff::a88:85a3::172.31.128.1
a:b:c:d:e:f:0::1
a:b:c:d:e:f:0::
total gibberish


Uiteraard zal de werkende validatie met jullie delen :)

Ik mijn gepruts grotendeels gebaseerd op
http://therealcrisp.xs4all.nl/blog/article-content/ipv6/ipv6.phps

En de IPv6 validatie van http://code.google.com/p/isemail/source/browse/trunk/is_email.php

Al naar Zend Framework gekeken, maar ook deze faalde in de testcases.

Ik ben nog geen steek verder.
Vooral: a:b:c:d:e::1.2.3.4, a:b:c:d:e:f::0, a::c:d:e:f:0:1 en a:b:c:d:e::1.2.3.4 krijg ik niet goed.

a:b:c:d:e:f::0 is wel geldig volgens mij, hoewel die laatste 0 zou komen te vervallen.

Dus welke IPv6 guru kan mij helpen.

mind
17/05/10, 11:23
Een paar maanden terug heb ik deze oplossing gezien op de ipv6 taskforce mailinglist

http://forums.dartware.com/viewtopic.php?t=452

Of eenvoudig in php:

function is_valid_ip($ip)
{
return(@inet_pton($ip) !== false);
}

Alleen nog even checken of het geen ipv4 adres is en klaar (zo ongeveer) ;-)


Succes er mee

Mikey
17/05/10, 11:37
wat je zoekt in php is filter_var & http://nl2.php.net/manual/en/filter.filters.validate.php

SebastiaanStok
17/05/10, 11:43
http://crisp.tweakblogs.net/blog/2031/ipv6-validation-%28and-caveats%29.html
Die werkt ook niet 100% :)

Overigens vaalt '1111:2222:3333::4444:5555:12.34.56.78'
Met de regex die Mind gaf. Dus... die is kennelijk ongeldig?

Edit: Volgens de testcase moet die ongeldig zijn, terwijl hij juist geldig is.
1111:2222:3333:4444::6666:123.123.123.123 Deze komt uit de Perl testcase en is geldig.
Kennelijk zit er een fout in mijn testcases... en die van de mail validator.

mind
17/05/10, 11:52
Overigens vaalt '1111:2222:3333::4444:5555:12.34.56.78'
Met de regex die Mind gaf. Dus... die is kennelijk ongeldig?
Dat is ook ongeldig aangezien dat alleen in het formaat ::ffff:192.0.2.128 geldig is. Zie http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_addresses en http://www.tcpipguide.com/free/t_IPv6IPv4AddressEmbedding-2.htm

Mikey
17/05/10, 12:11
waarom prutsen met regex als php zelf daar filters voor heeft ?

SebastiaanStok
17/05/10, 12:13
Ik heb de Perl testcases gebruikt, en die geven allemaal positief ( dus geen fouten ).
Ik zal de testcases van de mail even aanpassen :) bedankt voor de informatie.


waarom prutsen met regex als php zelf daar filters voor heeft ?
Omdat deze ook niet goed werkt :) ik heb hem even met de nieuwe testcases laten draaien, en daar krijg ik toch weer aardig wat fouten.

Deze is juist: 2001:0000:1234:0000:0000:C1C0:ABCD:0876 maar PHP vind van niet.
Ah het is een Toredo tunnel aldus Bitcricket IP Calculator.

Mikey
17/05/10, 12:23
Dan heb je je filter niet goed, hier wordt hij gemarkeerd als juist (2001:0000:1234:0000:0000:C1C0:ABCD:0876)

SebastiaanStok
17/05/10, 12:33
<?php
filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
?>

PHP5.3 op Windows Vista 32bit

Mikey
17/05/10, 12:35
hier op 5.2.6, 5.2.13 op linux zonder problemen.

SebastiaanStok
17/05/10, 12:58
Hmm, hij doet het :) alleen geeft hij geen boolean terug.
En in me testcase faalt hij, vreemd.

Ah gevonden, een spatie op het begin :) oh give me a break :thumbdown:
En nu doen ze het wel allemaal.

Allemaal bedankt voor de hulp en informatie.

groenleer
17/05/10, 15:18
Concreet:
<?php
filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
?>
Functioneert naar behoren met de eerder genoemde test adressen?

SebastiaanStok
17/05/10, 17:06
De testcases van Perl? Ja mits je $IP door trim() haalt.
Overigens zijn spaties voor of achter een IP-adres ook niet geldig, maar kennelijk wilde de maker hier tolerant in zijn.

Hier het volledige test script.



<?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 : '&nbsp;') . '</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 : '&nbsp') . '</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.

Mikey
17/05/10, 17:22
Concreet:
<?php
filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
?>
Functioneert naar behoren met de eerder genoemde test adressen?

ja wordt hier zonder problemen toegepast.

mind
17/05/10, 18:32
Bij IPv4-mapped IPv6 adressen laat filter_var wel de nodige steken vallen.

1::ffff:123.123.123.123 wordt onterecht goedgekeurd.
Even als 0:1:1:0:0:ffff:123.123.123.123 en nog vele andere combinaties.

Mikey
17/05/10, 22:04
Bij IPv4-mapped IPv6 adressen laat filter_var wel de nodige steken vallen.

1::ffff:123.123.123.123 wordt onterecht goedgekeurd.
Even als 0:1:1:0:0:ffff:123.123.123.123 en nog vele andere combinaties.

vul je toch een bug report in , mocht je van mening zijn dat hij niet klopt ;)

// er lopen al wat bug reports over, zal vanzelf meegenomen worden :)

SebastiaanStok
18/05/10, 11:13
Waarom is "0:1:1:0:0:ffff:123.123.123.123" ongeldig?
En dit betekend dat ik weer opzoek kan gaan naar een andere Regex.

Oké, en nu loopt Zend Studio vast :D



^(((?=(?>.*?::)(?!.*::)))(::)?([0-9A-F]{1,4}::?){0,5}|([0-9A-F]{1,4}:){6})(\2([0-9A-F]{1,4}(::?|$)){0,2}|((25[0-5]|(2[0-4]|1\d|[1-9])?\d)(\.|$)){4}|[0-9A-F]{1,4}:[0-9A-F]{1,4})(?<![^:]:|\.)\z

Deze werkt wel voor: 1::ffff:123.123.123.123 en 0:1:1:0:0:ffff:123.123.123.123, maar dan werkt hij weer niet voor andere tests. Argg...