IPv6Regex.psm1
<#
IPv6-Regex Chris Warwick, @cjwarwickps, October 2015 This PowerShell script tests a number of regular expressions that match text representations of IPv6 addresses. The script also runs the sample test cases against the [System.Net.IpAddress]::TryParse() method to illustrate some subtle considerations with address validation. See the end of the script for further notes. Script Structure ---------------- This script is split into four sections: 1. The first section defines an IPv6 regex to the tested against a set of sample addresses. A number of other Regexs gathered from across the web are also defined here. 2. Following the regex definitions, an array of test script-blocks is defined. Each script block takes a test IPv6 address as a parameter and tests this address against a specific regex or against the IpAddress.TryParse() method. The script blocks return true if the address is considered valid by the test or false otherwise. 3. The next (largest) section of the script defines sample IPv6 addresses to be tested. There are a large number of both valid and invalid address representations defined. 4. The final section of the script runs the tests. Each test script block is selected in turn and the test addresses are matched against the script blocks. Each test returns a test result object containing details of the individual test. The tests are timed to allow comparison of the performance of each test method (use the -Verbose switch to view timings). NOTE: The output of this script is most useful as a consolidated report. Consequently, the script 'breaks the rules' somewhat by including output formatting. This behaviour can be changed by specifying the '-NoFormat' switch parameter to instruct the script to pass test- result objects to the output pipeline (these can then be formatted or collected as required). Results ------- Unsurprisingly, a number of regexs found on the web are invalid (only one is included here, others have been omitted). Beware of using random regexs without testing them. There are some subtleties with the operation of the IpAddress.TestParse() method. 1. Both the regex and the IpAddress.TryParse() methods allow leading zeroes in the IPv4 octets. This is actually explicitly invalid in the definition in rfc3986 (apparently some systems (?) use a leading zero to denote an Octal number in the IPv4 Octet). 2. The IpAddress::TryParse method does not accept leading elided-zeroes syntax: ('::....') if there is only one group (the first group) of the address mising - although this is valid according to the RFC. So, for example, ::2:3:4:5:6:7 is considered valid by IpAddress::TryParse, but ::2:3:4:5:6:7:8 isn't 3. The IpAddress.TryParse() method by default accepts IPv4 addresses; these are qualified (filtered out) by checking the address against the [System.Net.Sockets.AddressFamily]::InterNetworkV6 type Compiling regexs is an expensive operation, and even for the relatively large number of tests defined here the investment is not warranted. Although the IpAddress.TryParse() method has some idiosyncrasies it may be preferred to the regex matching methods given the complexity of these regexs (IpAddress.TryParse is probably equally as complex but the complexity is at least hidden :-) #> Function IPv6Regex { [OutputType('RegexMatchResult')] [CmdletBinding()] Param ( $TestName, # Only run tests with names matching this (default = run all tests) [Switch]$NoFormat # Don't format the output (just retun TestResult objects) ) #region Script Section 1. IPv6 Address Regexs. # Some of these regexs are also compiled in order to compare performance # IPv6 addresses are comprised of groups of 1-4 Hex digits: $Hex = '[0-9a-f]{1,4}' # 1-4 hex characters (note: regex pattern is not case sensitive by default so "A-F" not included) # IPv6 addresses can have an embedded IPv4 address in the last 4 bytes. This regex matches IPv4 if present: # Component parts of an IPv4 Address Octet: ${250-255} = '25[0-5]' # Matches 3 digit numbers between 250 and 255 ${200-249} = '2[0-4]\d' # Matches 3 digit numbers between 200 and 249 ${100-199} = '1\d\d' # Matches 3 digit numbers between 100 and 199 ${0-99} = '[1-9]?[0-9]' # Matches 1 or 2 digit numbers between 0 and 99 # Each Octet is one of the four possible components defined above.. $Octet = "( ${250-255} | ${200-249} | ${100-199} | ${0-99} )" # IPv4 Address is 4 Octets separated by dots $IP4 = "($Octet\.){3}$Octet" $IPv6Regex = @" (?ix) # Use extended-mode regex (white-space, comments and newlines in the regex definition are ignored) ^\s* # Allow optional whitespace before the address # Note: All brackets are for grouping (the resulting captures are not used) ( (( $Hex :){7} ($Hex |:)) | # 8 Groups of 1-4 Hex characters, or 7 Groups with elided zeroes after 7th group (( $Hex :){6} (:$Hex | $IP4 |:)) | # Elided zeroes after 6th Group, or 6 Groups followed by dotted IP4 (( $Hex :){5} (((:$Hex){1,2})| : $IP4 |:)) | # g:g:g:g:g::g g:g:g:g:g::g:g g:g:g:g:g::ip4 g:g:g:g:g:: etc (( $Hex :){4} (((:$Hex){1,3})|((:$Hex)? : $IP4 )|:)) | # g:g:g:g::g g:g:g:g::g:g g:g:g:g::g:g:g g:g:g:g::ip4 g:g:g:g::g:ip4 g:g:g:g:: etc (( $Hex :){3} (((:$Hex){1,4})|((:$Hex){0,2}: $IP4 )|:)) | (( $Hex :){2} (((:$Hex){1,5})|((:$Hex){0,3}: $IP4 )|:)) | (( $Hex :){1} (((:$Hex){1,6})|((:$Hex){0,4}: $IP4 )|:)) | # g::g:g:g:g:g:g g::g:g:g:g:g ... g::g g:: g::g:g:g:g:ip4 .... g::ip4 etc (:(((: $Hex ){1,7})|((:$Hex){0,5} : $IP4 )|:)) # Elided zeroes at front of address: ::g:g:g:g:g:g:g ::g ::g:ip4 etc ) # (%.+)? # Match optional Zone Index (Scope ID) in Link Local address (there may be multiple link-local addresses (e.g. on different adapters) with different zone indexes) \s*$ # Allow optional whitespace at the end of the address "@ $CompiledIPv6Regex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList ($IPv6Regex,[System.Text.RegularExpressions.RegexOptions]::Compiled) # This sample is from the RegexBuddy Library $RegexBuddy = @' (?ix) \A(?: # Anchor address (?: # Mixed (?:[A-F0-9]{1,4}:){6} # Non-compressed |(?=(?:[A-F0-9]{0,4}:){2,6} # Compressed with 2 to 6 colons (?:[0-9]{1,3}\.){3}[0-9]{1,3} # and 4 bytes \z) # and anchored (([0-9A-F]{1,4}:){1,5}|:)((:[0-9A-F]{1,4}){1,5}:|:) # and at most 1 double colon |::(?:[A-F0-9]{1,4}:){5} # Compressed with 7 colons and 5 numbers ) (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3} # 255.255.255. (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]) # 255 | # Standard (?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4} # Standard | # Compressed (?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4} # Compressed with at most 7 colons \z) # and anchored (([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:) # and at most 1 double colon |(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7} # Compressed with 8 colons )\z # Anchor address '@ $CompiledRegexBuddy = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList ($RegexBuddy,[System.Text.RegularExpressions.RegexOptions]::Compiled) $Php1 = @' (?ix) \A (?: # mixed (?: # Non-compressed (?:[A-F0-9]{1,4}:){6} # Compressed with at most 6 colons |(?=(?:[A-F0-9]{0,4}:){0,6} (?:[0-9]{1,3}\.){3}[0-9]{1,3} # and 4 bytes \Z) # and anchored # and at most 1 double colon (([A-F0-9]{1,4}:){0,5}|:)((:[A-F0-9]{1,4}){1,5}:|:) ) # 255.255.255. (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} # 255 (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # Standard |(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4} # Compressed with at most 7 colons |(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4} \Z) # anchored # and at most 1 double colon (([A-F0-9]{1,4}:){1,7}|:)((:[A-F0-9]{1,4}){1,7}|:) )\Z '@ #endregion Script Section 1. IPv6 Address Regexs. #region Script Section 2. Test Method Script Blocks. # "$TestMethods" is an array of custom objects, each consisting of a test method name and a ScriptBlock that implements the test. # The ScriptBlock is passed a sample IPv6 address and returns True/False depending on whether the method considers the address valid. $TestMethods = @( # Test the IPv6 regex defined above [PsCustomObject] @{ Name = 'IPv6 Regex' ScriptBlock = { Param ([String]$TestAddress) Return ($TestAddress -Match $IPv6Regex) } } # Test the Compiled IPv6 regex defined above [PsCustomObject] @{ Name = 'Compiled IPv6 Regex' ScriptBlock = { Param ([String]$TestAddress) Return ($CompiledIPv6Regex.IsMatch($TestAddress)) } } [PsCustomObject] @{ Name = 'Php1' ScriptBlock = { Param ([String]$TestAddress) Return ($TestAddress -Match $Php1) } } [PsCustomObject] @{ Name = 'RegexBuddy' ScriptBlock = { Param ([String]$TestAddress) Return ($TestAddress -Match $RegexBuddy) } } [PsCustomObject] @{ Name = 'Compiled RegexBuddy' ScriptBlock = { Param ([String]$TestAddress) Return ($CompiledRegexBuddy.IsMatch($TestAddress)) } } # Tests using the [System.Net.IpAddress]::TryParse() method [PsCustomObject] @{ Name = 'Net IpAddress TryParse() Method' ScriptBlock = { Param ([String]$TestAddress) $IP = $Null Return ([System.Net.IPAddress]::TryParse($TestAddress,[Ref]$IP)) } } [PsCustomObject] @{ Name = 'Qualified Net IpAddress TryParse() Method' ScriptBlock = { Param ([String]$TestAddress) $IP = $Null If ([System.Net.IPAddress]::TryParse($TestAddress,[Ref]$IP)) { Return ($IP.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6) } else { Return $False } } } # .Net example from http://home.deds.nl/~aeron/regex/ [PsCustomObject] @{ Name = 'Aeron Regex' ScriptBlock = { Param ([String]$TestAddress) $Aeron = '^(((?=.*(::))(?!.*\3.+\3))\3?|[0-9A-F]{1,4}:)([0-9A-F]{1,4}(\3|:\b)|\2){5}(([0-9A-F]{1,4}(\3|:\b|$)|\2){2}|(((2[0-4]|1[0-9]|[1-9])?[0-9]|25[0-5])\.?\b){4})\z' Return ($TestAddress -Match $Aeron) } } ) #endregion Script Section 2. Test Method Script Blocks. #region Script Section 3. Test IPv6 Addresses. $Ipv6TestAddresses = @( [PsCustomObject] @{ Valid = $False; TestIPv6Address = '' } # empty string [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::1' } # loopback, compressed, non-routable [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::' } # unspecified, compressed, non-routable [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:0:0:1' } # loopback, full [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:0:0:0' } # unspecified, full [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:DB8:0:0:8:800:200C:417A' } # unicast, full [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FF01:0:0:0:0:0:0:101' } # multicast, full [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:DB8::8:800:200C:417A' } # unicast, compressed [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FF01::101' } # multicast, compressed [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:DB8:0:0:8:800:200C:417A:221' } # unicast, full [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'FF01::101::2' } # multicast, compressed [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::217:f2ff:fe07:ed62' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0000:1234:0000:0000:C1C0:ABCD:0876' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '3ffe:0b00:0000:0000:0001:0000:0000:000a' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FF02:0000:0000:0000:0000:0000:0000:0001' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0000:0000:0000:0000:0000:0000:0000:0001' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0000:0000:0000:0000:0000:0000:0000:0000' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '02001:0000:1234:0000:0000:C1C0:ABCD:0876' } # extra 0 not allowed [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:0000:1234:0000:00001:C1C0:ABCD:0876' } # extra 0 not allowed [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:0000:1234:0000:0000:C1C0:ABCD:0876 0' } # junk after valid address [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:0000:1234: 0000:0000:C1C0:ABCD:0876' } # internal space [PsCustomObject] @{ Valid = $False; TestIPv6Address = '3ffe:0b00:0000:0001:0000:0000:000a' } # seven segments [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'FF02:0000:0000:0000:0000:0000:0000:0000:0001' } # nine segments [PsCustomObject] @{ Valid = $False; TestIPv6Address = '3ffe:b00::1::a' } # double '::' [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1111:2222:3333:4444:5555:6666::' } # double '::' [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2::10' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'ff02::1' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2002::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:db8::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:1234::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::1' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5:6:7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5:6::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::2:3:4:5:6:7' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::2:3:4:5:6' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::2:3:4:5' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::2:3:4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::2:3' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3:4:5:6:7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3:4:5:6:7' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3:4:5:6' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3:4:5' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3:4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2:3' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5:6::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5::7:8' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1:2:3::4:5::7:8' } # Double '::' [PsCustomObject] @{ Valid = $False; TestIPv6Address = '12345::6:7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4::7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3::7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2::7:8' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::7:8' } # IPv4 addresses as dotted-quads [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5:6:1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4:5::1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4::1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3::1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2::1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3:4::5:1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2:3::5:1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1:2::5:1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::5:1.2.3.4' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1::5:11.22.33.44' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:400.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:260.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:256.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.256.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.256.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.3.256' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:300.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.300.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.300.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.3.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:900.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.900.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.900.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:1.2.3.900' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:300.300.300.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::5:3000.30.30.30' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::400.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::260.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::256.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.256.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.256.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.3.256' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::300.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.300.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.300.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.3.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::900.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.900.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.900.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::1.2.3.900' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::300.300.300.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::3000.30.30.30' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::400.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::260.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::256.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.256.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.256.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.3.256' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::300.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.300.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.300.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.3.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::900.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.900.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.900.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.3.900' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::300.300.300.300' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::3000.30.30.30' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::217:f2ff:254.7.237.98' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:192.168.1.26' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:1:1:1:1:1:255Z255X255Y255' } # garbage instead of '.' in IPv4 [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::ffff:192x168.1.26' } # ditto [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:192.168.1.1' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:0:13.1.68.3' } # IPv4-compatible IPv6 address, full, deprecated [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:FFFF:129.144.52.38' } # IPv4-mapped IPv6 address, full [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::13.1.68.3' } # IPv4-compatible IPv6 address, compressed, deprecated [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::FFFF:129.144.52.38' } # IPv4-mapped IPv6 address, compressed [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80:0:0:0:204:61ff:254.157.241.86' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::204:61ff:254.157.241.86' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:12.34.56.78' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::ffff:2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::ffff:257.1.2.3' } # [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4' } # Duplicate below [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4:1111:2222:3333:4444::5555' } # Aeron [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4:1111:2222:3333::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4:1111:2222::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4:1111::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '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 [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'fe80:0000:0000:0000:0204:61ff:254.157.241.086' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:192.0.2.128' } # but this is OK, since there's a single digit [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:00.00.00.00' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:000.000.000.000' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:256.256.256.256' } # Not testing address with subnet mask # [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0DB8:0000:CD30:0000:0000:0000:0000/60' } # full, with prefix # [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0DB8::CD30:0:0:0:0/60' } # compressed, with prefix # [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0DB8:0:CD30::/60' } # compressed, with prefix #2 # [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::/128' } # compressed, unspecified address type, non-routable # [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::1/128' } # compressed, loopback address type, non-routable # [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FF00::/8' } # compressed, multicast address type # [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FE80::/10' } # compressed, link-local unicast, non-routable # [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'FEC0::/10' } # compressed, site-local unicast, deprecated # [PsCustomObject] @{ Valid = $False; TestIPv6Address = '124.15.6.89/60' } # standard IPv4, prefix not allowed [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80:0000:0000:0000:0204:61ff:fe9d:f156' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80:0:0:0:204:61ff:fe9d:f156' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::204:61ff:fe9d:f156' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::1' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::1' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:c000:280' } # Aeron supplied these test cases [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } # Additional test cases # from http://rt.cpan.org/Public/Bug/Display.html?id=50693 [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:85a3:0000:0000:8a2e:0370:7334' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:db8:85a3:0:0:8a2e:370:7334' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:db8:85a3::8a2e:370:7334' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:0000:0000:0000:0000:1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:0000:0000:0000::1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:0:0:0:0:1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:0:0::1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8::1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:db8::1428:57ab' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0000:0000:0000:0000:0000:0000:0000:0001' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::1' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::ffff:0c22:384e' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:1234:0000:0000:0000:0000:0000' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '2001:db8:a::123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'fe80::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '123' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'ldkfj' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001::FFD3::57ab' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:db8:85a3::8a2e:37023:7334' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '2001:db8:85a3::8a2e:370k:7334' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1:2:3:4:5:6:7:8:9' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1::2::3' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1:::3:4:5' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1:2:3::4:5:6:7:8:9' } # From Aeron [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::3333:4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2222:3333:4444:5555:6666:123.123.123.123' } # Combinations of '0' and '::' # NB: these are all sytactically correct, but are bad form # because '0' adjacent to '::' should be combined into '::' [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0:0:0:0:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0:0:0:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0:0:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:0::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0::' } # New invalid from Aeron # Invalid data [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX' } # Too many components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:9999' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888:9999' } # Too few components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111' } # Missing : [PsCustomObject] @{ Valid = $False; TestIPv6Address = '11112222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:22223333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:33334444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:44445555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:55556666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:66667777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:77778888' } # Missing : intended for :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:7777:8888' } # ::: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:::' } # Double ::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:7777::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:7777:8888::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::7777::' } # Too many components' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:1.2.3.4.5' } # Too few components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4' } # Missing : [PsCustomObject] @{ Valid = $False; TestIPv6Address = '11112222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:22223333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:33334444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:44445555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:55556666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:66661.2.3.4' } # Missing . [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255255.255.255' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255.255255.255' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255.255.255255' } # Missing : intended for :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:1.2.3.4' } # ::: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::1.2.3.4' } # Double :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555::1.2.3.4' } # Missing parts [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::...' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1...' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2.3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::...4' } # Extra : in front [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:1.2.3.4' } # Extra : at end [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888:' } # Additional cases: http://crisp.tweakblogs.net/blog/2031/ipv6-validation-%28and-caveats%29.html [PsCustomObject] @{ Valid = $True; TestIPv6Address = '0:a:b:c:d:e:f::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::0:a:b:c:d:e:f' } # syntactically correct, but bad form (::0:... could be combined) [PsCustomObject] @{ Valid = $True; TestIPv6Address = 'a:b:c:d:e:f:0::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':10.0.0.1' } # Further test cases... ## From: http://home.deds.nl/~aeron/regex/valid_ipv6.txt [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444:5555::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333:4444::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222:3333::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111:2222::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '1111::3333:4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::3333:4444:5555:6666:123.123.123.123' } [PsCustomObject] @{ Valid = $True; TestIPv6Address = '::2222:3333:4444:5555:6666:123.123.123.123' } ## From: http://home.deds.nl/~aeron/regex/invalid_ipv6.txt # Invalid data [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX' } # To many components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:9999' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888:9999' } # To few components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111' } # Missing : [PsCustomObject] @{ Valid = $False; TestIPv6Address = '11112222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:22223333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:33334444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:44445555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:55556666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:66667777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:77778888' } # Missing : intended for :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:7777:8888' } # ::: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:::' } # Double :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:7777::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:7777:8888::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::7777::' } # Invalid data [PsCustomObject] @{ Valid = $False; TestIPv6Address = 'XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:00.00.00.00' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:000.000.000.000' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:256.256.256.256' } # To few components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:1.2.3.4.5' } # To few components [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1.2.3.4' } # Missing : [PsCustomObject] @{ Valid = $False; TestIPv6Address = '11112222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:22223333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:33334444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:44445555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:55556666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:66661.2.3.4' } # Missing . [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255255.255.255' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255.255255.255' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:255.255.255255' } # Missing : intended for :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:1.2.3.4' } # ::: [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::1.2.3.4' } # Double :: [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555::1.2.3.4' } # Missing parts [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::...' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1...' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::1.2.3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2..' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2.3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..3.' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::..3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::...4' } # Extra : in front [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:7777::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:7777:8888' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444:5555::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333:4444::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222:3333::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111:2222::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':1111::3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::3333:4444:5555:6666:1.2.3.4' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::2222:3333:4444:5555:6666:1.2.3.4' } # Extra : at end [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:7777:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = ':::' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555:6666::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444:5555::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333:4444::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222:3333::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111:2222::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '1111::3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::3333:4444:5555:6666:7777:8888:' } [PsCustomObject] @{ Valid = $False; TestIPv6Address = '::2222:3333:4444:5555:6666:7777:8888:' } ) #endregion Script Section 3. Test IPv6 Addresses. #region Script Section 4. Main Code. # Run each of the test methods against the list of test addresses $UniqueTests = $IPv6TestAddresses | Sort-Object -Property TestIPv6Address -Unique $TestResults = @() # We have to gather the result objects manually rather than just emitting them to the pipeline because Measure-Command will discard them otherwise Foreach ($Test in ($TestMethods | Where-Object Name -Match $TestName)) { $TestFailedCount = 0 $Elapsed = Measure-Command { Foreach ($TestAddress in $UniqueTests) { $TestResult = & $Test.ScriptBlock $TestAddress.TestIPv6Address $Passed = ($TestAddress.Valid -Eq $TestResult) If (-Not $Passed) {$TestFailedCount++} $TestResults += [PsCustomObject] @{ PsTypeName = 'RegexMatchResult' TestName = $Test.Name TestAddress = $TestAddress.TestIPv6Address ExpectedResult = $TestAddress.Valid ActualResult = $TestResult Pass = $Passed } } } Write-Verbose ("{0,2} of {1} unique tests failed in {2,4:F0}ms for '{3}'" -f $TestFailedCount, $UniqueTests.Count, $Elapsed.TotalMilliseconds, $Test.Name) } # Todo: leave the filtering and formatting out of the script... (but just interested in failures for now) # Format the output unless requested not to... If ($NoFormat) { $TestResults # Just output the result objects } Else { # Format the collected test result objects; show only failing tests... $TestResults | Where-Object {-not $_.Pass} | Format-Table TestName, TestAddress, ExpectedResult, ActualResult -AutoSize } #endregion Script Section 4. Main Code. } # End Function Ipv6Regex <# Additional Notes. This script is inspired by a Perl script from here: http://download.dartware.com/thirdparty/test-ipv6-regex.pl However, some of the regexs are new or significantly refactored. A large number of the test address cases are taken from this site of from others sites linked from this page. Overview: The regex matches the following IPv6 address forms. Note that these are all the same address: fe80:0000:0000:0000:0204:61ff:fe9d:f156 -- full form of IPv6 fe80:0:0:0:204:61ff:fe9d:f156 -- drop leading zeroes fe80::204:61ff:fe9d:f156 -- collapse multiple zeroes to :: in the IPv6 address fe80:0000:0000:0000:0204:61ff:254.157.241.86 -- IPv4 dotted quad at the end fe80:0:0:0:0204:61ff:254.157.241.86 -- drop leading zeroes, IPv4 dotted quad at the end fe80::204:61ff:254.157.241.86 -- dotted quad at the end, multiple zeroes collapsed In addition, the regular expression matches these IPv6 forms: ::1 -- localhost fe80:: -- link-local prefix 2001:: -- global unicast prefix Link Local addresses may have a Scope-ID (or Zone Index) at the end of the address following a percent sign. The Scope Id will be the adapter index (in Windows). The Scope ID is used to distinguish between multiple similar link local addresses on different interfaces. http://msdn.microsoft.com/en-us/library/aa921042.aspx The regex here can test for Scope IDs, but this is currently commented out of the regex (see code below) See http://www.ietf.org/rfc/rfc4291.txt "IP Version 6 Addressing Architecture" Section 2.2 "Text Representation of Addresses" (An extract of this section of the RFC is included at the end of this script) ...and http://tools.ietf.org/html/rfc5952 (Updates rfc4291) Also see: http://www.ietf.org/rfc/rfc3986.txt "Uniform Resource Identifier (URI): Generic Syntax" Section 3.2.2 Syntax Components - Host (An extract of this section of the RFC is included at the end of this script) And: http://tools.ietf.org/html/rfc4007 "IPv6 Scoped Address Architecture" http://en.wikipedia.org/wiki/IPv6_address Todo: Add -StrictIPv4 switch (for leading 0 in IPv4 Octet) #------------------------------------------------------------------------------ Further Background: There are a number of RFCs covering IPv6 formats. Some relevent extracts are included here: From http://www.ietf.org/rfc/rfc4291.txt "IP Version 6 Addressing Architecture" 2.2. Text Representation of Addresses There are three conventional forms for representing IPv6 addresses as text strings: 1. The preferred form is x:x:x:x:x:x:x:x, where the 'x's are one to four hexadecimal digits of the eight 16-bit pieces of the address. Examples: ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 2001:DB8:0:0:8:800:200C:417A Note that it is not necessary to write the leading zeros in an individual field, but there must be at least one numeral in every field (except for the case described in 2.). 2. Due to some methods of allocating certain styles of IPv6 addresses, it will be common for addresses to contain long strings of zero bits. In order to make writing addresses containing zero bits easier, a special syntax is available to compress the zeros. The use of "::" indicates one or more groups of 16 bits of zeros. The "::" can only appear once in an address. The "::" can also be used to compress leading or trailing zeros in an address. For example, the following addresses 2001:DB8:0:0:8:800:200C:417A a unicast address FF01:0:0:0:0:0:0:101 a multicast address 0:0:0:0:0:0:0:1 the loopback address 0:0:0:0:0:0:0:0 the unspecified address may be represented as 2001:DB8::8:800:200C:417A a unicast address FF01::101 a multicast address ::1 the loopback address :: the unspecified address 3. An alternative form that is sometimes more convenient when dealing with a mixed environment of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values of the six high-order 16-bit pieces of the address, and the 'd's are the decimal values of the four low-order 8-bit pieces of the address (standard IPv4 representation). Examples: 0:0:0:0:0:0:13.1.68.3 0:0:0:0:0:FFFF:129.144.52.38 or in compressed form: ::13.1.68.3 ::FFFF:129.144.52.38 2.3. Text Representation of Address Prefixes The text representation of IPv6 address prefixes is similar to the way IPv4 address prefixes are written in Classless Inter-Domain Routing (CIDR) notation [CIDR]. An IPv6 address prefix is represented by the notation: ipv6-address/prefix-length where ipv6-address is an IPv6 address in any of the notations listed in Section 2.2. prefix-length is a decimal value specifying how many of the leftmost contiguous bits of the address comprise the prefix. For example, the following are legal representations of the 60-bit prefix 20010DB80000CD3 (hexadecimal): 2001:0DB8:0000:CD30:0000:0000:0000:0000/60 2001:0DB8::CD30:0:0:0:0/60 2001:0DB8:0:CD30::/60 The following are NOT legal representations of the above prefix: 2001:0DB8:0:CD3/60 may drop leading zeros, but not trailing zeros, within any 16-bit chunk of the address 2001:0DB8::CD30/60 address to left of "/" expands to 2001:0DB8:0000:0000:0000:0000:0000:CD30 2001:0DB8::CD3/60 address to left of "/" expands to 2001:0DB8:0000:0000:0000:0000:0000:0CD3 When writing both a node address and a prefix of that node address (e.g., the node's subnet prefix), the two can be combined as follows: the node address 2001:0DB8:0:CD30:123:4567:89AB:CDEF and its subnet number 2001:0DB8:0:CD30::/60 can be abbreviated as 2001:0DB8:0:CD30:123:4567:89AB:CDEF/60 #------------------------------------------------------------------------------ From: http://www.ietf.org/rfc/rfc3986.txt "Uniform Resource Identifier (URI): Generic Syntax" Section 3.2.2 Syntax Components - Host A 128-bit IPv6 address is divided into eight 16-bit pieces. Each piece is represented numerically in case-insensitive hexadecimal, using one to four hexadecimal digits (leading zeroes are permitted). The eight encoded pieces are given most-significant first, separated by colon characters. Optionally, the least-significant two pieces may instead be represented in IPv4 address textual format. A sequence of one or more consecutive zero-valued 16-bit pieces within the address may be elided, omitting all their digits and leaving exactly two consecutive colons in their place to mark the elision. IPv6address = 6( h16 ":" ) ls32 / "::" 5( h16 ":" ) ls32 / [ h16 ] "::" 4( h16 ":" ) ls32 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 / [ *4( h16 ":" ) h16 ] "::" ls32 / [ *5( h16 ":" ) h16 ] "::" h16 / [ *6( h16 ":" ) h16 ] "::" ls32 = ( h16 ":" h16 ) / IPv4address ; least-significant 32 bits of address h16 = 1*4HEXDIG ; 16 bits of address represented in hexadecimal A host identified by an IPv4 literal address is represented in dotted-decimal notation (a sequence of four decimal numbers in the range 0 to 255, separated by "."), as described in [RFC1123] by reference to [RFC0952]. Note that other forms of dotted notation may be interpreted on some platforms, as described in Section 7.4, but only the dotted-decimal form of four octets is allowed by this grammar. IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet dec-octet = DIGIT ; 0-9 / %x31-39 DIGIT ; 10-99 / "1" 2DIGIT ; 100-199 / "2" %x30-34 DIGIT ; 200-249 / "25" %x30-35 ; 250-255 #------------------------------------------------------------------------------ Additional ad-hoc References: https://gist.github.com/cpetschnig/294476 -- Ruby IPv6 validator http://people.spodhuis.org/phil.pennock/software/emit_ipv6_regexp-0.304 -- Uses syntax from rfc3986 http://download.dartware.com/thirdparty/test-ipv6-regex.pl -- Perl Script http://crisp.tweakblogs.net/blog/2031/ipv6-validation-%28and-caveats%29.html -- PHP and Test cases http://crisp.tweakblogs.net/blog/3049/ipv6-validation-more-caveats.html -- PHP and Test cases http://home.deds.nl/~aeron/regex/ -- shortest regexs - various flavours http://home.deds.nl/~aeron/regex/valid_ipv6.txt -- Valid IPv6 addresses test cases http://home.deds.nl/~aeron/regex/invalid_ipv6.txt -- Invalid IPv6 addresses test cases http://msdn.microsoft.com/en-us/library/aa915659.aspx -- IPv6 http://msdn.microsoft.com/en-us/library/aa917150.aspx -- IPv6 Addressing http://msdn.microsoft.com/en-us/library/aa921042.aspx -- IPv6 Addresses http://msdn.microsoft.com/en-us/library/windows/desktop/aa385325(v=vs.85).aspx -- Zone index Many examples from: http://download.dartware.com/thirdparty/test-ipv6-regex.pl Main reference http://www.rfc-editor.org/rfc/rfc3986.txt Other Regexs.... Three samples from http://download.dartware.com/thirdparty/test-ipv6-regex.pl $aeron = qr/^(((?=(?>.*?::)(?!.*::)))(::)?([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[0-9]|[1-9])?[0-9])(\.|$)){4}|[0-9A-F]{1,4}:[0-9A-F]{1,4})(?<![^:]:)(?<!\.)\z/i; $dartware = qr/^\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*$/; ~~~~~~~~~~~~~~~~~~~~ Ruby example from https://gist.github.com/cpetschnig/294476 IPV6_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*$/ ~~~~~~~~~~~~~~~~~~~~ Perl example based on rfc from: http://people.spodhuis.org/phil.pennock/software/emit_ipv6_regexp-0.304 # Phil Pennock who submitted a RE generated automatically from the full grammar in RFC3986 # http://people.spodhuis.org/phil.pennock/software/emit_ipv6_regexp-0.304 $philpennock = qr/^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/; # RFC 3986 states: # IPv6address = 6( h16 ":" ) ls32 # / "::" 5( h16 ":" ) ls32 # / [ h16 ] "::" 4( h16 ":" ) ls32 # / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 # / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 # / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 # / [ *4( h16 ":" ) h16 ] "::" ls32 # / [ *5( h16 ":" ) h16 ] "::" h16 # / [ *6( h16 ":" ) h16 ] "::" # # ls32 = ( h16 ":" h16 ) / IPv4address # ; least-significant 32 bits of address # # h16 = 1*4HEXDIG my $IPV4_OCTET = qr/(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])/; my $IPV4_REGEXP = qr/(?:(?:${IPV4_OCTET}\.){3}${IPV4_OCTET})/o; my $IPV6_H16 = qr/(?:[0-9a-fA-F]{1,4})/; my $IPV6_LS32 = qr/(?:(?:${IPV6_H16}:${IPV6_H16})|${IPV4_REGEXP})/o; my $IPV6_REGEXP = qr/(?: (?:(?: (?:${IPV6_H16}:){6} )${IPV6_LS32}) | (?:(?: :: (?:${IPV6_H16}:){5} )${IPV6_LS32}) | (?:(?: (?: ${IPV6_H16} )? :: (?:${IPV6_H16}:){4} )${IPV6_LS32}) | (?:(?: (?: (?:${IPV6_H16}:){0,1} ${IPV6_H16} )? :: (?:${IPV6_H16}:){3} )${IPV6_LS32}) | (?:(?: (?: (?:${IPV6_H16}:){0,2} ${IPV6_H16} )? :: (?:${IPV6_H16}:){2} )${IPV6_LS32}) | (?:(?: (?: (?:${IPV6_H16}:){0,3} ${IPV6_H16} )? :: ${IPV6_H16}: )${IPV6_LS32}) | (?:(?: (?: (?:${IPV6_H16}:){0,4} ${IPV6_H16} )? :: )${IPV6_LS32}) | (?:(?: (?: (?:${IPV6_H16}:){0,5} ${IPV6_H16} )? :: )${IPV6_H16} ) | (?:(?: (?: (?:${IPV6_H16}:){0,6} ${IPV6_H16} )? :: ) ) )/ox; ~~~~~~~~~~~~~~~~~~~~~~~~~~ PHP Regex by "WCP" in comment on http://crisp.tweakblogs.net/blog/2031/ipv6-validation-%28and-caveats%29.html $dec_octet = "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"; $ipv4address = "($dec_octet\.){3}$dec_octet"; $h16 = "[0-9a-fA-F]{1,4}"; $ls32 = "($h16:$h16|$ipv4address)"; $ipv6address = "(" . "(" . "($h16:){6}" . "|" . "::($h16:){5}" . "|" . "($h16)?::($h16:){4}" . "|" . "(($h16:){0,1}$h16)?::($h16:){3}" . "|" . "(($h16:){0,2}$h16)?::($h16:){2}" . "|" . "(($h16:){0,3}$h16)?::$h16:" . "|" . "(($h16:){0,4}$h16)?::" . ")" . "$ls32" . "|" . "(" . "(($h16:){0,5}$h16)?::$h16" . "|" . "(($h16:){0,6}$h16)?::" . ")" . ")"; ~~~~~~~~~~~~~~~~~~~~~~~~~~ PHP Function/Regex from http://crisp.tweakblogs.net/blog/3049/ipv6-validation-more-caveats.html function validateIPv4($IP) { return $IP == long2ip(ip2long($IP)); } function validateIPv6($IP) { if (strlen($IP) < 3) return $IP == '::'; if (strpos($IP, '.')) { $lastcolon = strrpos($IP, ':'); if (!($lastcolon && validateIPv4(substr($IP, $lastcolon + 1)))) return false; $IP = substr($IP, 0, $lastcolon) . ':0:0'; } if (strpos($IP, '::') === false) { return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $IP); } $colonCount = substr_count($IP, ':'); 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); } // 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); } return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~ PHP regex from the Regular Expression Cookbook chapter 7.17 'Matching IPv6 Addresses' on page 387. by Jan Goyvaerts and Steven Levithan function validateIPv6($IP) { return preg_match('/\A (?: # mixed (?: # Non-compressed (?:[A-F0-9]{1,4}:){6} # Compressed with at most 6 colons |(?=(?:[A-F0-9]{0,4}:){0,6} (?:[0-9]{1,3}\.){3}[0-9]{1,3} # and 4 bytes \Z) # and anchored # and at most 1 double colon (([A-F0-9]{1,4}:){0,5}|:)((:[A-F0-9]{1,4}){1,5}:|:) ) # 255.255.255. (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} # 255 (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # Standard |(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4} # Compressed with at most 7 colons |(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4} \Z) # anchored # and at most 1 double colon (([A-F0-9]{1,4}:){1,7}|:)((:[A-F0-9]{1,4}){1,7}|:) )\Z/ix', $IP ); } #> |