IPv6 validation

20,023

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

Share:
20,023
Isabel Jinson
Author by

Isabel Jinson

Updated on August 04, 2020

Comments

  • Isabel Jinson
    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

    1. ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
    2. 2001:DB8:0:0:8:800:200C:417A
    3. FF01:0:0:0:0:0:0:101
    4. 0:0:0:0:0:0:0:1
    5. 0:0:0:0:0:0:0:0
    6. 2001:DB8::8:800:200C:417A
    7. FF01::101
    8. ::1
    9. ::
    10. 0:0:0:0:0:0:13.1.68.3
    11. 0:0:0:0:0:FFFF:129.144.52.38
    12. ::13.1.68.3
    13. FFFF:129.144.52.38
    14. 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
    15. 2001:0DB8::CD30:0:0:0:0/60
    16. 2001:0DB8:0:CD30::/60

    NOT legal representations of IPV6

    1. 2001:0DB8:0:CD3/60
    2. 2001:0DB8::CD30/60
    3. 2001:0DB8::CD3/60
  • Mike Pennington
    Mike Pennington almost 13 years
    the 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
    Gordon almost 13 years
    For 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
    psy almost 7 years
    It does not work for IPv6 prefixes. Only works for IPv6 addresses. @broc.seib
  • Sinc
    Sinc about 6 years
    This doesn't appear to even try to handle the :: versions and the ones that end with an IPv4 address.
  • Gubatron
    Gubatron over 5 years
    A 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
    deepakl.2000 almost 3 years
    Can you post the complete Java solution for IPV6 validation ?