public boolean isValidInet6Address()

in src/main/java/org/apache/commons/validator/routines/InetAddressValidator.java [134:220]


    public boolean isValidInet6Address(String inet6Address) {
        String[] parts;
        // remove prefix size. This will appear after the zone id (if any)
        parts = inet6Address.split("/", -1);
        if (parts.length > 2) {
            return false; // can only have one prefix specifier
        }
        if (parts.length == 2) {
            if (!DIGITS_PATTERN.matcher(parts[1]).matches()) {
                return false; // not a valid number
            }
            final int bits = Integer.parseInt(parts[1]); // cannot fail because of RE check
            if (bits < 0 || bits > MAX_BYTE) {
                return false; // out of range
            }
        }
        // remove zone-id
        parts = parts[0].split("%", -1);
        // The id syntax is implementation independent, but it presumably cannot allow:
        // whitespace, '/' or '%'
        if ((parts.length > 2) || (parts.length == 2 && !ID_CHECK_PATTERN.matcher(parts[1]).matches())) {
            return false; // invalid id
        }
        inet6Address = parts[0];
        final boolean containsCompressedZeroes = inet6Address.contains("::");
        if (containsCompressedZeroes && inet6Address.indexOf("::") != inet6Address.lastIndexOf("::")) {
            return false;
        }
        final boolean startsWithCompressed = inet6Address.startsWith("::");
        final boolean endsWithCompressed = inet6Address.endsWith("::");
        final boolean endsWithSep = inet6Address.endsWith(":");
        if (inet6Address.startsWith(":") && !startsWithCompressed || endsWithSep && !endsWithCompressed) {
            return false;
        }
        String[] octets = inet6Address.split(":");
        if (containsCompressedZeroes) {
            final List<String> octetList = new ArrayList<>(Arrays.asList(octets));
            if (endsWithCompressed) {
                // String.split() drops ending empty segments
                octetList.add("");
            } else if (startsWithCompressed && !octetList.isEmpty()) {
                octetList.remove(0);
            }
            octets = octetList.toArray(new String[0]);
        }
        if (octets.length > IPV6_MAX_HEX_GROUPS) {
            return false;
        }
        int validOctets = 0;
        int emptyOctets = 0; // consecutive empty chunks
        for (int index = 0; index < octets.length; index++) {
            final String octet = octets[index];
            if (GenericValidator.isBlankOrNull(octet)) {
                emptyOctets++;
                if (emptyOctets > 1) {
                    return false;
                }
            } else {
                emptyOctets = 0;
                // Is last chunk an IPv4 address?
                if (index == octets.length - 1 && octet.contains(".")) {
                    if (!isValidInet4Address(octet)) {
                        return false;
                    }
                    validOctets += 2;
                    continue;
                }
                if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) {
                    return false;
                }
                int octetInt = 0;
                try {
                    octetInt = Integer.parseInt(octet, BASE_16);
                } catch (final NumberFormatException e) {
                    return false;
                }
                if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) {
                    return false;
                }
            }
            validOctets++;
        }
        if (validOctets > IPV6_MAX_HEX_GROUPS || validOctets < IPV6_MAX_HEX_GROUPS && !containsCompressedZeroes) {
            return false;
        }
        return true;
    }