IPv6 validation
Solution 1
See if this works:
try {
if (subjectString.matches(
"(?ix)\\A(?: # Anchor address\n" +
" (?: # Mixed\n" +
" (?:[A-F0-9]{1,4}:){6} # Non-compressed\n" +
" |(?=(?:[A-F0-9]{0,4}:){2,6} # Compressed with 2 to 6 colons\n" +
" (?:[0-9]{1,3}\\.){3}[0-9]{1,3} # and 4 bytes\n" +
" \\z) # and anchored\n" +
" (([0-9A-F]{1,4}:){1,5}|:)((:[0-9A-F]{1,4}){1,5}:|:) # and at most 1 double colon\n" +
" |::(?:[A-F0-9]{1,4}:){5} # Compressed with 7 colons and 5 numbers\n" +
" )\n" +
" (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3} # 255.255.255.\n" +
" (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]) # 255\n" +
"| # Standard\n" +
" (?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4} # Standard\n" +
"| # Compressed\n" +
" (?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4} # Compressed with at most 7 colons\n" +
" \\z) # and anchored\n" +
" (([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:) # and at most 1 double colon\n" +
"|(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7} # Compressed with 8 colons\n" +
")/[A-F0-9]{0,4}\\z # Anchor address"))
{
// String matched entirely
} else {
// Match attempt failed
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
I purchased a very helpful program called RegexMagic nearly a year ago for some complicated regular expressions I planned on using.
This was suppose to be Java, so it should compile, I assume the /60 can be between the ranges of 0000 and FFFF you can modify that last part.
/[A-F0-9]{0,4} is what I added to the regular expression to match your example.
Solution 2
You can use the Guava library, specifically using the com.google.common.net.InetAddresses
class, calling isInetAddress()
.
isInetAddress
public static boolean isInetAddress(String ipString)
Returns true if the supplied string is a valid IP string literal, false otherwise.
Parameters: ipString
- String to evaluated as an IP string literal
Returns: true
if the argument is a valid IP string literal
Solution 3
The IPAddress Java library supports parsing both IPv4 and IPv6 CIDR subnets (ie address/prefix format) in a polymorphic manner. Disclaimer: I am the project manager.
The following method is example code for validating:
static void parse(String str) {
IPAddressString addrString = new IPAddressString(str);
try {
IPAddress addr = addrString.toAddress();
IPAddress hostAddr = addrString.toHostAddress();
Integer prefix = addr.getNetworkPrefixLength();
if(prefix == null) {
System.out.println(addr + " has no prefix length");
} else {
System.out.println(addr + " has host address " + hostAddr + " and prefix length " + prefix);
}
} catch(AddressStringException e) {
System.out.println(addrString + " is invalid: " + e.getMessage());
}
}
Using the examples provided in the question, the output of the above method is:
abcd:ef01:2345:6789:abcd:ef01:2345:6789 has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
::d01:4403 has no prefix length
::ffff:8190:3426 has no prefix length
::d01:4403 has no prefix length
FFFF:129.144.52.38 is invalid: FFFF:129.144.52.38 IP Address error: address has too few segments
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:0DB8:0:CD3/60 is invalid: 2001:0DB8:0:CD3/60 IP Address error: address has too few segments
2001:db8::cd30/60 has host address 2001:db8::cd30 and prefix length 60
2001:db8::cd3/60 has host address 2001:db8::cd3 and prefix length 60
As you can see, the question was incorrect about FFFF:129.144.52.38 being valid and about 2001:db8::cd30/60 and 2001:db8::cd3/60 being invalid. The first one would be valid if it were ::FFFF:129.144.52.38
Isabel Jinson
Updated on August 04, 2020Comments
-
Isabel Jinson almost 4 years
I used
IPAddressUtil.isIPv6LiteralAddress (ipAddress)
method to validate IPv6, but this method fails for ipv6-address/prefix-length format (format is mentioned in RFC 4291 section 2.3) of IPV6.Could anyone know any validators which validate " ipv6-address/prefix-length " format?
Legal representations of IPV6
- ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
- 2001:DB8:0:0:8:800:200C:417A
- FF01:0:0:0:0:0:0:101
- 0:0:0:0:0:0:0:1
- 0:0:0:0:0:0:0:0
- 2001:DB8::8:800:200C:417A
- FF01::101
- ::1
- ::
- 0:0:0:0:0:0:13.1.68.3
- 0:0:0:0:0:FFFF:129.144.52.38
- ::13.1.68.3
- FFFF:129.144.52.38
- 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
- 2001:0DB8::CD30:0:0:0:0/60
- 2001:0DB8:0:CD30::/60
NOT legal representations of IPV6
- 2001:0DB8:0:CD3/60
- 2001:0DB8::CD30/60
- 2001:0DB8::CD3/60
-
Mike Pennington almost 13 yearsthe Regex above might work... but this is so ginormous, I can't imagine someone (including the original author) having a clue how to dissect it a year later. Instead of chaining so many
|
, I would break it into a bunch of "else if" statements, which at a minimum facilitates much easier debugging -
Gordon almost 13 yearsFor IPv4, it is 0-32. For IPv6, it is 0-128. 32 or 128 would be a single address, 31 or 127 would be two addresses, 30 or 126 would be four addresses, etc.
-
psy almost 7 yearsIt does not work for IPv6 prefixes. Only works for IPv6 addresses. @broc.seib
-
Sinc about 6 yearsThis doesn't appear to even try to handle the :: versions and the ones that end with an IPv4 address.
-
Gubatron over 5 yearsA slight modification to the IPV6 pattern: Pattern VALID_IPV6_PATTERN = Pattern.compile("([0-9a-f]{1,4}:{1,2}){4,7}([0-9a-f]){1,4}", java.util.regex.Pattern.CASE_INSENSITIVE);
-
deepakl.2000 almost 3 yearsCan you post the complete Java solution for IPV6 validation ?