IPv6 validation

前端 未结 6 876
抹茶落季
抹茶落季 2021-01-01 22:06

I used IPAddressUtil.isIPv6LiteralAddress (ipAddress) method to validate IPv6, but this method fails for ipv6-address/prefix-length format (format is mentioned

相关标签:
6条回答
  • 2021-01-01 22:39

    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.

    0 讨论(0)
  • 2021-01-01 22:40

    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

    0 讨论(0)
  • 2021-01-01 22:45

    Strictly speaking, a section 2.3 does not describe an address representation, but a representation of address prefix (even the "full-length" prefix is not the same as an address).

    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.

    That means you may safely disregard this format if you need to validate addresses.

    0 讨论(0)
  • 2021-01-01 22:47

    My idea is to split it into two part, prefix address and prefix len.

    1. validate prefix address use the some regex to validate IPv6 address
    2. validate the prefix len that must be an integer
    3. prefix address can only have ':' s less than the result ofprefix len divided by 16
    4. other logic must be considered as well, leave TODOs here, sorry:(

      private int validateIPv6AddrWithPrefix(String address) {
            int occurCount = 0;
            for(char c : address) {
                if(c=='/'){
                    occurCount++;
                }
            }
            if(occurCount != 1){
             //not good, to much / character
                return -1;
            }
            /* 2nd element should be an integer */
            String[] ss = pool.getAddress().split("/");
            Integer prefixLen = null;
            try{
                prefixLen = Integer.valueOf(ss[1]);
                        // TODO validate the prefix range(1, 128)
    
            }catch(NumberFormatException e) {
                /* not a Integer */
                return -1;
            }
            /* 1st element should be ipv6 address */
            if(!IPaddrUtilities.isIPv6Address(ss[0])) {
                return -1;
            }
            /* validate ':' character logic */
            occurCount = 0;
            for(char c : ss[0].toCharArray()){
                if(c==':') {
                    occurCount++;
                }
            }
            if(occurCount >= prefixLen/16) {
                // to much ':' character
                return -1;
            }
            return 0;
        }
    
    0 讨论(0)
  • 2021-01-01 22:52

    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

    0 讨论(0)
  • 2021-01-01 23:02

    I had tried below regex in java and it worked for IPV4 and IPV6

    public class Utilities {
    private static Pattern VALID_IPV4_PATTERN = null;
    private static Pattern VALID_IPV6_PATTERN = null;
    private static final String ipv4Pattern = "(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])";
    private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}";
    
    static {
    try {
      VALID_IPV4_PATTERN = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE);
      VALID_IPV6_PATTERN = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE);
       } catch (PatternSyntaxException e) {
      //logger.severe("Unable to compile pattern", e);
     }
    }
    
     /**
     * Determine if the given string is a valid IPv4 or IPv6 address.  This method
     * uses pattern matching to see if the given string could be a valid IP address.
     *
     * @param ipAddress A string that is to be examined to verify whether or not
     * it could be a valid IP address.
     * @return <code>true</code> if the string is a value that is a valid IP address,
     *  <code>false</code> otherwise.
     */
     public static boolean isIpAddress(String ipAddress) {
    
    Matcher m1 = Utilities.VALID_IPV4_PATTERN.matcher(ipAddress);
    if (m1.matches()) {
      return true;
    }
    Matcher m2 = Utilities.VALID_IPV6_PATTERN.matcher(ipAddress);
    return m2.matches();
      }
    
    
    }
    
    0 讨论(0)
提交回复
热议问题