IPv6 parse, regex vs. function

Benchmark created on


Setup

window.ipv6testfn = null;
    var success = 0
    var failure = 0;
    window.doIPv6Test = function(valid, str) {
        var result = window.ipv6testfn(str);
        if (result === valid) {
            success++;
        } else {
            failure++;
        }
    }
    
    window.isIPv4 = function(ip) {
        var i,
            octet;
        if (typeof ip !== 'string') {
            return false;
        }
        ip = ip.split('.');
        if (ip.length !== 4) {
            return false;
        }
        for (i = 0; i < 4; i++) {
            if ((ip[i].length === 3 && ip[i][0] === '0') || (ip[i].length === 2 && ip[i][0] === '0') || (ip[i].length === 0)) {
                return false;
            }
            octet = parseInt(ip[i], 10);
            if (octet < 0 || octet > 255) {
                return false;
            }
        }
        return true;
    }
    
    window.runIPv6Tests = function() {
        doIPv6Test(false, '')// empty string 
        doIPv6Test(true, '::1')// loopback, compressed, non-routable 
        doIPv6Test(true, '::')// unspecified, compressed, non-routable 
        doIPv6Test(true, '0:0:0:0:0:0:0:1')// loopback, full 
        doIPv6Test(true, '0:0:0:0:0:0:0:0')// unspecified, full 
        doIPv6Test(true, '2001:DB8:0:0:8:800:200C:417A')// unicast, full 
        doIPv6Test(true, 'FF01:0:0:0:0:0:0:101')// multicast, full 
        doIPv6Test(true, '2001:DB8::8:800:200C:417A')// unicast, compressed 
        doIPv6Test(true, 'FF01::101')// multicast, compressed 
        doIPv6Test(false, '2001:DB8:0:0:8:800:200C:417A:221')// unicast, full 
        doIPv6Test(false, 'FF01::101::2')// multicast, compressed 
        doIPv6Test(true, 'fe80::217:f2ff:fe07:ed62')
    
        doIPv6Test(true, '2001:0000:1234:0000:0000:C1C0:ABCD:0876')
        doIPv6Test(true, '3ffe:0b00:0000:0000:0001:0000:0000:000a')
        doIPv6Test(true, 'FF02:0000:0000:0000:0000:0000:0000:0001')
        doIPv6Test(true, '0000:0000:0000:0000:0000:0000:0000:0001')
        doIPv6Test(true, '0000:0000:0000:0000:0000:0000:0000:0000')
        doIPv6Test(false, '02001:0000:1234:0000:0000:C1C0:ABCD:0876')    // extra 0 not allowed! 
        doIPv6Test(false, '2001:0000:1234:0000:00001:C1C0:ABCD:0876')    // extra 0 not allowed! 
    //    doIPv6Test(true, ' 2001:0000:1234:0000:0000:C1C0:ABCD:0876')        # leading space
    //    doIPv6Test(true, '2001:0000:1234:0000:0000:C1C0:ABCD:0876')     # trailing space
    //    doIPv6Test(true, ' 2001:0000:1234:0000:0000:C1C0:ABCD:0876  ')  # leading and trailing space
        doIPv6Test(false, '2001:0000:1234:0000:0000:C1C0:ABCD:0876  0')  // junk after valid address
        doIPv6Test(false, '2001:0000:1234: 0000:0000:C1C0:ABCD:0876')    // internal space
    
        doIPv6Test(false, '3ffe:0b00:0000:0001:0000:0000:000a')          // seven segments
        doIPv6Test(false, 'FF02:0000:0000:0000:0000:0000:0000:0000:0001')    // nine segments
        doIPv6Test(false, '3ffe:b00::1::a')                              // double "::"
        doIPv6Test(false, '::1111:2222:3333:4444:5555:6666::')           // double "::"
        doIPv6Test(true, '2::10')
        doIPv6Test(true, 'ff02::1')
        doIPv6Test(true, 'fe80::')
        doIPv6Test(true, '2002::')
        doIPv6Test(true, '2001:db8::')
        doIPv6Test(true, '2001:0db8:1234::')
        doIPv6Test(true, '::ffff:0:0')
        doIPv6Test(true, '::1')
        doIPv6Test(true, '1:2:3:4:5:6:7:8')
        doIPv6Test(true, '1:2:3:4:5:6::8')
        doIPv6Test(true, '1:2:3:4:5::8')
        doIPv6Test(true, '1:2:3:4::8')
        doIPv6Test(true, '1:2:3::8')
        doIPv6Test(true, '1:2::8')
        doIPv6Test(true, '1::8')
        doIPv6Test(true, '1::2:3:4:5:6:7')
        doIPv6Test(true, '1::2:3:4:5:6')
        doIPv6Test(true, '1::2:3:4:5')
        doIPv6Test(true, '1::2:3:4')
        doIPv6Test(true, '1::2:3')
        doIPv6Test(true, '1::8')
        doIPv6Test(true, '::2:3:4:5:6:7:8')
        doIPv6Test(true, '::2:3:4:5:6:7')
        doIPv6Test(true, '::2:3:4:5:6')
        doIPv6Test(true, '::2:3:4:5')
        doIPv6Test(true, '::2:3:4')
        doIPv6Test(true, '::2:3')
        doIPv6Test(true, '::8')
        doIPv6Test(true, '1:2:3:4:5:6::')
        doIPv6Test(true, '1:2:3:4:5::')
        doIPv6Test(true, '1:2:3:4::')
        doIPv6Test(true, '1:2:3::')
        doIPv6Test(true, '1:2::')
        doIPv6Test(true, '1::')
        doIPv6Test(true, '1:2:3:4:5::7:8')
        doIPv6Test(false, '1:2:3::4:5::7:8')                         // Double "::"
        doIPv6Test(false, '12345::6:7:8')
        doIPv6Test(true, '1:2:3:4::7:8')
        doIPv6Test(true, '1:2:3::7:8')
        doIPv6Test(true, '1:2::7:8')
        doIPv6Test(true, '1::7:8')
    
    // IPv4 addresses as dotted-quads
        doIPv6Test(true, '1:2:3:4:5:6:1.2.3.4')
        doIPv6Test(true, '1:2:3:4:5::1.2.3.4')
        doIPv6Test(true, '1:2:3:4::1.2.3.4')
        doIPv6Test(true, '1:2:3::1.2.3.4')
        doIPv6Test(true, '1:2::1.2.3.4')
        doIPv6Test(true, '1::1.2.3.4')
        doIPv6Test(true, '1:2:3:4::5:1.2.3.4')
        doIPv6Test(true, '1:2:3::5:1.2.3.4')
        doIPv6Test(true, '1:2::5:1.2.3.4')
        doIPv6Test(true, '1::5:1.2.3.4')
        doIPv6Test(true, '1::5:11.22.33.44')
        doIPv6Test(false, '1::5:400.2.3.4')
        doIPv6Test(false, '1::5:260.2.3.4')
        doIPv6Test(false, '1::5:256.2.3.4')
        doIPv6Test(false, '1::5:1.256.3.4')
        doIPv6Test(false, '1::5:1.2.256.4')
        doIPv6Test(false, '1::5:1.2.3.256')
        doIPv6Test(false, '1::5:300.2.3.4')
        doIPv6Test(false, '1::5:1.300.3.4')
        doIPv6Test(false, '1::5:1.2.300.4')
        doIPv6Test(false, '1::5:1.2.3.300')
        doIPv6Test(false, '1::5:900.2.3.4')
        doIPv6Test(false, '1::5:1.900.3.4')
        doIPv6Test(false, '1::5:1.2.900.4')
        doIPv6Test(false, '1::5:1.2.3.900')
        doIPv6Test(false, '1::5:300.300.300.300')
        doIPv6Test(false, '1::5:3000.30.30.30')
        doIPv6Test(false, '1::400.2.3.4')
        doIPv6Test(false, '1::260.2.3.4')
        doIPv6Test(false, '1::256.2.3.4')
        doIPv6Test(false, '1::1.256.3.4')
        doIPv6Test(false, '1::1.2.256.4')
        doIPv6Test(false, '1::1.2.3.256')
        doIPv6Test(false, '1::300.2.3.4')
        doIPv6Test(false, '1::1.300.3.4')
        doIPv6Test(false, '1::1.2.300.4')
        doIPv6Test(false, '1::1.2.3.300')
        doIPv6Test(false, '1::900.2.3.4')
        doIPv6Test(false, '1::1.900.3.4')
        doIPv6Test(false, '1::1.2.900.4')
        doIPv6Test(false, '1::1.2.3.900')
        doIPv6Test(false, '1::300.300.300.300')
        doIPv6Test(false, '1::3000.30.30.30')
        doIPv6Test(false, '::400.2.3.4')
        doIPv6Test(false, '::260.2.3.4')
        doIPv6Test(false, '::256.2.3.4')
        doIPv6Test(false, '::1.256.3.4')
        doIPv6Test(false, '::1.2.256.4')
        doIPv6Test(false, '::1.2.3.256')
        doIPv6Test(false, '::300.2.3.4')
        doIPv6Test(false, '::1.300.3.4')
        doIPv6Test(false, '::1.2.300.4')
        doIPv6Test(false, '::1.2.3.300')
        doIPv6Test(false, '::900.2.3.4')
        doIPv6Test(false, '::1.900.3.4')
        doIPv6Test(false, '::1.2.900.4')
        doIPv6Test(false, '::1.2.3.900')
        doIPv6Test(false, '::300.300.300.300')
        doIPv6Test(false, '::3000.30.30.30')
        doIPv6Test(true, 'fe80::217:f2ff:254.7.237.98')
        doIPv6Test(true, '::ffff:192.168.1.26')
        doIPv6Test(false, '2001:1:1:1:1:1:255Z255X255Y255')              // garbage instead of "." in IPv4
        doIPv6Test(false, '::ffff:192x168.1.26')                         // ditto
        doIPv6Test(true, '::ffff:192.168.1.1')
        doIPv6Test(true, '0:0:0:0:0:0:13.1.68.3')// IPv4-compatible IPv6 address, full, deprecated 
        doIPv6Test(true, '0:0:0:0:0:FFFF:129.144.52.38')// IPv4-mapped IPv6 address, full 
        doIPv6Test(true, '::13.1.68.3')// IPv4-compatible IPv6 address, compressed, deprecated 
        doIPv6Test(true, '::FFFF:129.144.52.38')// IPv4-mapped IPv6 address, compressed 
        doIPv6Test(true, 'fe80:0:0:0:204:61ff:254.157.241.86')
        doIPv6Test(true, 'fe80::204:61ff:254.157.241.86')
        doIPv6Test(true, '::ffff:12.34.56.78')
        doIPv6Test(false, '::ffff:2.3.4')
        doIPv6Test(false, '::ffff:257.1.2.3')
        doIPv6Test(false, '1.2.3.4')
    
        doIPv6Test(false, '1.2.3.4:1111:2222:3333:4444::5555')  // Aeron
        doIPv6Test(false, '1.2.3.4:1111:2222:3333::5555')
        doIPv6Test(false, '1.2.3.4:1111:2222::5555')
        doIPv6Test(false, '1.2.3.4:1111::5555')
        doIPv6Test(false, '1.2.3.4::5555')
        doIPv6Test(false, '1.2.3.4::')
    
    // Testing IPv4 addresses represented as dotted-quads
    // Leading zero's in IPv4 addresses not allowed: some systems treat the leading "0" in ".086" as the start of an octal number
    // Update: The BNF in RFC-3986 explicitly defines the dec-octet (for IPv4 addresses) not to have a leading zero
        doIPv6Test(false, 'fe80:0000:0000:0000:0204:61ff:254.157.241.086')
        doIPv6Test(true, '::ffff:192.0.2.128')   // but this is OK, since there's a single digit
        doIPv6Test(false, 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:00.00.00.00')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:000.000.000.000')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:256.256.256.256')
    
    // Not testing address with subnet mask
    //     doIPv6Test(true, '2001:0DB8:0000:CD30:0000:0000:0000:0000/60')# full, with prefix 
    //     doIPv6Test(true, '2001:0DB8::CD30:0:0:0:0/60')# compressed, with prefix 
    //     doIPv6Test(true, '2001:0DB8:0:CD30::/60')# compressed, with prefix #2 
    //     doIPv6Test(true, '::/128')# compressed, unspecified address type, non-routable 
    //     doIPv6Test(true, '::1/128')# compressed, loopback address type, non-routable 
    //     doIPv6Test(true, 'FF00::/8')# compressed, multicast address type 
    //     doIPv6Test(true, 'FE80::/10')# compressed, link-local unicast, non-routable 
    //     doIPv6Test(true, 'FEC0::/10')# compressed, site-local unicast, deprecated 
    //     doIPv6Test(false, '124.15.6.89/60')# standard IPv4, prefix not allowed 
    
        doIPv6Test(true, 'fe80:0000:0000:0000:0204:61ff:fe9d:f156')
        doIPv6Test(true, 'fe80:0:0:0:204:61ff:fe9d:f156')
        doIPv6Test(true, 'fe80::204:61ff:fe9d:f156')
        doIPv6Test(true, '::1')
        doIPv6Test(true, 'fe80::')
        doIPv6Test(true, 'fe80::1')
        doIPv6Test(false, ':')
        doIPv6Test(true, '::ffff:c000:280')
    
    // Aeron supplied these test cases
        doIPv6Test(false, '1111:2222:3333:4444::5555:')
        doIPv6Test(false, '1111:2222:3333::5555:')
        doIPv6Test(false, '1111:2222::5555:')
        doIPv6Test(false, '1111::5555:')
        doIPv6Test(false, '::5555:')
        doIPv6Test(false, ':::')
        doIPv6Test(false, '1111:')
        doIPv6Test(false, ':')
    
        doIPv6Test(false, ':1111:2222:3333:4444::5555')
        doIPv6Test(false, ':1111:2222:3333::5555')
        doIPv6Test(false, ':1111:2222::5555')
        doIPv6Test(false, ':1111::5555')
        doIPv6Test(false, ':::5555')
        doIPv6Test(false, ':::')
    
    
    // Additional test cases
    // from http://rt.cpan.org/Public/Bug/Display.html?id=50693
    
        doIPv6Test(true, '2001:0db8:85a3:0000:0000:8a2e:0370:7334')
        doIPv6Test(true, '2001:db8:85a3:0:0:8a2e:370:7334')
        doIPv6Test(true, '2001:db8:85a3::8a2e:370:7334')
        doIPv6Test(true, '2001:0db8:0000:0000:0000:0000:1428:57ab')
        doIPv6Test(true, '2001:0db8:0000:0000:0000::1428:57ab')
        doIPv6Test(true, '2001:0db8:0:0:0:0:1428:57ab')
        doIPv6Test(true, '2001:0db8:0:0::1428:57ab')
        doIPv6Test(true, '2001:0db8::1428:57ab')
        doIPv6Test(true, '2001:db8::1428:57ab')
        doIPv6Test(true, '0000:0000:0000:0000:0000:0000:0000:0001')
        doIPv6Test(true, '::1')
        doIPv6Test(true, '::ffff:0c22:384e')
        doIPv6Test(true, '2001:0db8:1234:0000:0000:0000:0000:0000')
        doIPv6Test(true, '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff')
        doIPv6Test(true, '2001:db8:a::123')
        doIPv6Test(true, 'fe80::')
    
        doIPv6Test(false, '123')
        doIPv6Test(false, 'ldkfj')
        doIPv6Test(false, '2001::FFD3::57ab')
        doIPv6Test(false, '2001:db8:85a3::8a2e:37023:7334')
        doIPv6Test(false, '2001:db8:85a3::8a2e:370k:7334')
        doIPv6Test(false, '1:2:3:4:5:6:7:8:9')
        doIPv6Test(false, '1::2::3')
        doIPv6Test(false, '1:::3:4:5')
        doIPv6Test(false, '1:2:3::4:5:6:7:8:9')
    
    // New from Aeron 
        doIPv6Test(true, '1111:2222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(true, '1111:2222:3333:4444:5555:6666:7777::')
        doIPv6Test(true, '1111:2222:3333:4444:5555:6666::')
        doIPv6Test(true, '1111:2222:3333:4444:5555::')
        doIPv6Test(true, '1111:2222:3333:4444::')
        doIPv6Test(true, '1111:2222:3333::')
        doIPv6Test(true, '1111:2222::')
        doIPv6Test(true, '1111::')
    //     doIPv6Test(true, '::')     #duplicate
        doIPv6Test(true, '1111:2222:3333:4444:5555:6666::8888')
        doIPv6Test(true, '1111:2222:3333:4444:5555::8888')
        doIPv6Test(true, '1111:2222:3333:4444::8888')
        doIPv6Test(true, '1111:2222:3333::8888')
        doIPv6Test(true, '1111:2222::8888')
        doIPv6Test(true, '1111::8888')
        doIPv6Test(true, '::8888')
        doIPv6Test(true, '1111:2222:3333:4444:5555::7777:8888')
        doIPv6Test(true, '1111:2222:3333:4444::7777:8888')
        doIPv6Test(true, '1111:2222:3333::7777:8888')
        doIPv6Test(true, '1111:2222::7777:8888')
        doIPv6Test(true, '1111::7777:8888')
        doIPv6Test(true, '::7777:8888')
        doIPv6Test(true, '1111:2222:3333:4444::6666:7777:8888')
        doIPv6Test(true, '1111:2222:3333::6666:7777:8888')
        doIPv6Test(true, '1111:2222::6666:7777:8888')
        doIPv6Test(true, '1111::6666:7777:8888')
        doIPv6Test(true, '::6666:7777:8888')
        doIPv6Test(true, '1111:2222:3333::5555:6666:7777:8888')
        doIPv6Test(true, '1111:2222::5555:6666:7777:8888')
        doIPv6Test(true, '1111::5555:6666:7777:8888')
        doIPv6Test(true, '::5555:6666:7777:8888')
        doIPv6Test(true, '1111:2222::4444:5555:6666:7777:8888')
        doIPv6Test(true, '1111::4444:5555:6666:7777:8888')
        doIPv6Test(true, '::4444:5555:6666:7777:8888')
        doIPv6Test(true, '1111::3333:4444:5555:6666:7777:8888')
        doIPv6Test(true, '::3333:4444:5555:6666:7777:8888')
        doIPv6Test(true, '::2222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(true, '1111:2222:3333:4444:5555:6666:123.123.123.123')
        doIPv6Test(true, '1111:2222:3333:4444:5555::123.123.123.123')
        doIPv6Test(true, '1111:2222:3333:4444::123.123.123.123')
        doIPv6Test(true, '1111:2222:3333::123.123.123.123')
        doIPv6Test(true, '1111:2222::123.123.123.123')
        doIPv6Test(true, '1111::123.123.123.123')
        doIPv6Test(true, '::123.123.123.123')
        doIPv6Test(true, '1111:2222:3333:4444::6666:123.123.123.123')
        doIPv6Test(true, '1111:2222:3333::6666:123.123.123.123')
        doIPv6Test(true, '1111:2222::6666:123.123.123.123')
        doIPv6Test(true, '1111::6666:123.123.123.123')
        doIPv6Test(true, '::6666:123.123.123.123')
        doIPv6Test(true, '1111:2222:3333::5555:6666:123.123.123.123')
        doIPv6Test(true, '1111:2222::5555:6666:123.123.123.123')
        doIPv6Test(true, '1111::5555:6666:123.123.123.123')
        doIPv6Test(true, '::5555:6666:123.123.123.123')
        doIPv6Test(true, '1111:2222::4444:5555:6666:123.123.123.123')
        doIPv6Test(true, '1111::4444:5555:6666:123.123.123.123')
        doIPv6Test(true, '::4444:5555:6666:123.123.123.123')
        doIPv6Test(true, '1111::3333:4444:5555:6666:123.123.123.123')
        doIPv6Test(true, '::2222:3333:4444:5555:6666:123.123.123.123')
    
    // Playing with combinations of "0" and "::"
    // NB: these are all sytactically correct, but are bad form 
    //   because "0" adjacent to "::" should be combined into "::"
        doIPv6Test(true, '::0:0:0:0:0:0:0')
        doIPv6Test(true, '::0:0:0:0:0:0')
        doIPv6Test(true, '::0:0:0:0:0')
        doIPv6Test(true, '::0:0:0:0')
        doIPv6Test(true, '::0:0:0')
        doIPv6Test(true, '::0:0')
        doIPv6Test(true, '::0')
        doIPv6Test(true, '0:0:0:0:0:0:0::')
        doIPv6Test(true, '0:0:0:0:0:0::')
        doIPv6Test(true, '0:0:0:0:0::')
        doIPv6Test(true, '0:0:0:0::')
        doIPv6Test(true, '0:0:0::')
        doIPv6Test(true, '0:0::')
        doIPv6Test(true, '0::')
    
    // New invalid from Aeron
    // Invalid data
        doIPv6Test(false, 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX')
    
    // Too many components
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:8888:9999')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:8888::')
        doIPv6Test(false, '::2222:3333:4444:5555:6666:7777:8888:9999')
    
    // Too few components
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666')
        doIPv6Test(false, '1111:2222:3333:4444:5555')
        doIPv6Test(false, '1111:2222:3333:4444')
        doIPv6Test(false, '1111:2222:3333')
        doIPv6Test(false, '1111:2222')
        doIPv6Test(false, '1111')
    
    // Missing :
        doIPv6Test(false, '11112222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:22223333:4444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:33334444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:44445555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:55556666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:5555:66667777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:77778888')
    
    // Missing : intended for ::
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:8888:')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:')
        doIPv6Test(false, '1111:2222:3333:4444:5555:')
        doIPv6Test(false, '1111:2222:3333:4444:')
        doIPv6Test(false, '1111:2222:3333:')
        doIPv6Test(false, '1111:2222:')
        doIPv6Test(false, '1111:')
        doIPv6Test(false, ':')
        doIPv6Test(false, ':8888')
        doIPv6Test(false, ':7777:8888')
        doIPv6Test(false, ':6666:7777:8888')
        doIPv6Test(false, ':5555:6666:7777:8888')
        doIPv6Test(false, ':4444:5555:6666:7777:8888')
        doIPv6Test(false, ':3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, ':2222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666:7777:8888')
    
    // :::
        doIPv6Test(false, ':::2222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:::3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:::4444:5555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:::5555:6666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:::6666:7777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:5555:::7777:8888')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:::8888')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:::')
    
    // Double ::");
        doIPv6Test(false, '::2222::4444:5555:6666:7777:8888')
        doIPv6Test(false, '::2222:3333::5555:6666:7777:8888')
        doIPv6Test(false, '::2222:3333:4444::6666:7777:8888')
        doIPv6Test(false, '::2222:3333:4444:5555::7777:8888')
        doIPv6Test(false, '::2222:3333:4444:5555:7777::8888')
        doIPv6Test(false, '::2222:3333:4444:5555:7777:8888::')
    
        doIPv6Test(false, '1111::3333::5555:6666:7777:8888')
        doIPv6Test(false, '1111::3333:4444::6666:7777:8888')
        doIPv6Test(false, '1111::3333:4444:5555::7777:8888')
        doIPv6Test(false, '1111::3333:4444:5555:6666::8888')
        doIPv6Test(false, '1111::3333:4444:5555:6666:7777::')
    
        doIPv6Test(false, '1111:2222::4444::6666:7777:8888')
        doIPv6Test(false, '1111:2222::4444:5555::7777:8888')
        doIPv6Test(false, '1111:2222::4444:5555:6666::8888')
        doIPv6Test(false, '1111:2222::4444:5555:6666:7777::')
    
        doIPv6Test(false, '1111:2222:3333::5555::7777:8888')
        doIPv6Test(false, '1111:2222:3333::5555:6666::8888')
        doIPv6Test(false, '1111:2222:3333::5555:6666:7777::')
    
        doIPv6Test(false, '1111:2222:3333:4444::6666::8888')
        doIPv6Test(false, '1111:2222:3333:4444::6666:7777::')
    
        doIPv6Test(false, '1111:2222:3333:4444:5555::7777::')
    
    
    // Too many components"
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666::1.2.3.4')
        doIPv6Test(false, '::2222:3333:4444:5555:6666:7777:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:1.2.3.4.5')
    
    // Too few components
        doIPv6Test(false, '1111:2222:3333:4444:5555:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:1.2.3.4')
        doIPv6Test(false, '1111:2222:1.2.3.4')
        doIPv6Test(false, '1111:1.2.3.4')
        doIPv6Test(false, '1.2.3.4')
    
    // Missing :
        doIPv6Test(false, '11112222:3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:22223333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:33334444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:44445555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:55556666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:66661.2.3.4')
    
    // Missing .
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:255255.255.255')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:255.255255.255')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:255.255.255255')
    
    // Missing : intended for ::
        doIPv6Test(false, ':1.2.3.4')
        doIPv6Test(false, ':6666:1.2.3.4')
        doIPv6Test(false, ':5555:6666:1.2.3.4')
        doIPv6Test(false, ':4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':2222:3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666:1.2.3.4')
    
    // :::
        doIPv6Test(false, ':::2222:3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:::3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:::4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:::5555:6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:::6666:1.2.3.4')
        doIPv6Test(false, '1111:2222:3333:4444:5555:::1.2.3.4')
    
    // Double ::
        doIPv6Test(false, '::2222::4444:5555:6666:1.2.3.4')
        doIPv6Test(false, '::2222:3333::5555:6666:1.2.3.4')
        doIPv6Test(false, '::2222:3333:4444::6666:1.2.3.4')
        doIPv6Test(false, '::2222:3333:4444:5555::1.2.3.4')
    
        doIPv6Test(false, '1111::3333::5555:6666:1.2.3.4')
        doIPv6Test(false, '1111::3333:4444::6666:1.2.3.4')
        doIPv6Test(false, '1111::3333:4444:5555::1.2.3.4')
    
        doIPv6Test(false, '1111:2222::4444::6666:1.2.3.4')
        doIPv6Test(false, '1111:2222::4444:5555::1.2.3.4')
    
        doIPv6Test(false, '1111:2222:3333::5555::1.2.3.4')
    
    // Missing parts
        doIPv6Test(false, '::.')
        doIPv6Test(false, '::..')
        doIPv6Test(false, '::...')
        doIPv6Test(false, '::1...')
        doIPv6Test(false, '::1.2..')
        doIPv6Test(false, '::1.2.3.')
        doIPv6Test(false, '::.2..')
        doIPv6Test(false, '::.2.3.')
        doIPv6Test(false, '::.2.3.4')
        doIPv6Test(false, '::..3.')
        doIPv6Test(false, '::..3.4')
        doIPv6Test(false, '::...4')
    
    // Extra : in front
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666:7777::')
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666::')
        doIPv6Test(false, ':1111:2222:3333:4444:5555::')
        doIPv6Test(false, ':1111:2222:3333:4444::')
        doIPv6Test(false, ':1111:2222:3333::')
        doIPv6Test(false, ':1111:2222::')
        doIPv6Test(false, ':1111::')
        doIPv6Test(false, ':::')
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666::8888')
        doIPv6Test(false, ':1111:2222:3333:4444:5555::8888')
        doIPv6Test(false, ':1111:2222:3333:4444::8888')
        doIPv6Test(false, ':1111:2222:3333::8888')
        doIPv6Test(false, ':1111:2222::8888')
        doIPv6Test(false, ':1111::8888')
        doIPv6Test(false, ':::8888')
        doIPv6Test(false, ':1111:2222:3333:4444:5555::7777:8888')
        doIPv6Test(false, ':1111:2222:3333:4444::7777:8888')
        doIPv6Test(false, ':1111:2222:3333::7777:8888')
        doIPv6Test(false, ':1111:2222::7777:8888')
        doIPv6Test(false, ':1111::7777:8888')
        doIPv6Test(false, ':::7777:8888')
        doIPv6Test(false, ':1111:2222:3333:4444::6666:7777:8888')
        doIPv6Test(false, ':1111:2222:3333::6666:7777:8888')
        doIPv6Test(false, ':1111:2222::6666:7777:8888')
        doIPv6Test(false, ':1111::6666:7777:8888')
        doIPv6Test(false, ':::6666:7777:8888')
        doIPv6Test(false, ':1111:2222:3333::5555:6666:7777:8888')
        doIPv6Test(false, ':1111:2222::5555:6666:7777:8888')
        doIPv6Test(false, ':1111::5555:6666:7777:8888')
        doIPv6Test(false, ':::5555:6666:7777:8888')
        doIPv6Test(false, ':1111:2222::4444:5555:6666:7777:8888')
        doIPv6Test(false, ':1111::4444:5555:6666:7777:8888')
        doIPv6Test(false, ':::4444:5555:6666:7777:8888')
        doIPv6Test(false, ':1111::3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, ':::3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, ':::2222:3333:4444:5555:6666:7777:8888')
        doIPv6Test(false, ':1111:2222:3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333:4444:5555::1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333:4444::1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333::1.2.3.4')
        doIPv6Test(false, ':1111:2222::1.2.3.4')
        doIPv6Test(false, ':1111::1.2.3.4')
        doIPv6Test(false, ':::1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333:4444::6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333::6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222::6666:1.2.3.4')
        doIPv6Test(false, ':1111::6666:1.2.3.4')
        doIPv6Test(false, ':::6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222:3333::5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222::5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111::5555:6666:1.2.3.4')
        doIPv6Test(false, ':::5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111:2222::4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111::4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':::4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':1111::3333:4444:5555:6666:1.2.3.4')
        doIPv6Test(false, ':::2222:3333:4444:5555:6666:1.2.3.4')
    
    // Extra : at end
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:7777:::')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666:::')
        doIPv6Test(false, '1111:2222:3333:4444:5555:::')
        doIPv6Test(false, '1111:2222:3333:4444:::')
        doIPv6Test(false, '1111:2222:3333:::')
        doIPv6Test(false, '1111:2222:::')
        doIPv6Test(false, '1111:::')
        doIPv6Test(false, ':::')
        doIPv6Test(false, '1111:2222:3333:4444:5555:6666::8888:')
        doIPv6Test(false, '1111:2222:3333:4444:5555::8888:')
        doIPv6Test(false, '1111:2222:3333:4444::8888:')
        doIPv6Test(false, '1111:2222:3333::8888:')
        doIPv6Test(false, '1111:2222::8888:')
        doIPv6Test(false, '1111::8888:')
        doIPv6Test(false, '::8888:')
        doIPv6Test(false, '1111:2222:3333:4444:5555::7777:8888:')
        doIPv6Test(false, '1111:2222:3333:4444::7777:8888:')
        doIPv6Test(false, '1111:2222:3333::7777:8888:')
        doIPv6Test(false, '1111:2222::7777:8888:')
        doIPv6Test(false, '1111::7777:8888:')
        doIPv6Test(false, '::7777:8888:')
        doIPv6Test(false, '1111:2222:3333:4444::6666:7777:8888:')
        doIPv6Test(false, '1111:2222:3333::6666:7777:8888:')
        doIPv6Test(false, '1111:2222::6666:7777:8888:')
        doIPv6Test(false, '1111::6666:7777:8888:')
        doIPv6Test(false, '::6666:7777:8888:')
        doIPv6Test(false, '1111:2222:3333::5555:6666:7777:8888:')
        doIPv6Test(false, '1111:2222::5555:6666:7777:8888:')
        doIPv6Test(false, '1111::5555:6666:7777:8888:')
        doIPv6Test(false, '::5555:6666:7777:8888:')
        doIPv6Test(false, '1111:2222::4444:5555:6666:7777:8888:')
        doIPv6Test(false, '1111::4444:5555:6666:7777:8888:')
        doIPv6Test(false, '::4444:5555:6666:7777:8888:')
        doIPv6Test(false, '1111::3333:4444:5555:6666:7777:8888:')
        doIPv6Test(false, '::3333:4444:5555:6666:7777:8888:')
        doIPv6Test(false, '::2222:3333:4444:5555:6666:7777:8888:')
    
    // Additional cases: http://crisp.tweakblogs.net/blog/2031/ipv6-validation-%28and-caveats%29.html
        doIPv6Test(true, '0:a:b:c:d:e:f::')
        doIPv6Test(true, '::0:a:b:c:d:e:f') // syntactically correct, but bad form (::0:... could be combined)
        doIPv6Test(true, 'a:b:c:d:e:f:0::')
        doIPv6Test(false, ':10.0.0.1')
    }

Test runner

Ready to run.

Testing in
TestOps/sec
function
window.ipv6testfn = function (ip) {
    "use strict";
    var i = 0,
        seen_double_colon = false,
        starts_with_double_colon = false,
        dotted_quad = false;
    if (typeof ip !== 'string') {
        return false;
    }
    ip = ip.split(':');
    if (ip[0] === '') {
        if (ip[1] !== '') {
            return false;
        }
        if (arguments[0] === ':') {
            return false;
        }
        seen_double_colon = true;
        starts_with_double_colon = true;
        i = 2;
    }
    if (ip.length > 8) {
        if (ip.length === 9) {
            if (!(starts_with_double_colon || arguments[0].substr(-2) === '::')) {
                return false;
            }
        } else {
            return false;
        }
    }
    if (ip.length === 1) {
        return false;
    }
    if (i < ip.length) {
        for (; i < ip.length; i++) {
            if ((i === ip.length -1) && (isIPv4(ip[i]))) {
                if ((ip.length === 7 || (ip.length <= 8 && starts_with_double_colon) || ip.length <= 6 && seen_double_colon)) {
                    dotted_quad = true;
                    continue;
                } else {
                    return false;
                }
            }
            if (ip[i].length > 4) {
                return false;
            }
            if (ip[i].length === 0) {
                if (seen_double_colon) {
                    if (i !== (ip.length - 1)) {
                        return false;
                    } else {
                        if (ip[i-1] !== '') {
                            return false;
                        }
                    }
                } else {
                    if (i == (ip.length - 1)) {
                        return false;
                    } else {
                        seen_double_colon = true;
                    }
                }
            }
            if (ip[i].match(/[^0-9a-fA-F]/)) {
                return false;
            }
        }
    }
    if (ip.length < 8 && !seen_double_colon && !dotted_quad) {
        return false;
    }
    return true;
}
ready
regex (Dartware)
window.ipv6testfn = function (ip) {
    var regex = /^\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*$/;
    return ip.match(regex);
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.