inet.ipaddr

Class IPAddressString

  • java.lang.Object
    • inet.ipaddr.IPAddressString
  • All Implemented Interfaces:
    HostIdentifierString, java.io.Serializable, java.lang.Comparable<IPAddressString>


    public class IPAddressString
    extends java.lang.Object
    implements HostIdentifierString, java.lang.Comparable<IPAddressString>
    Parses the string representation of an IP address. Such a string can represent just a single address like 1.2.3.4 or 1:2:3:4:6:7:8, or a subnet like 1.2.0.0/16 or 1.*.1-3.1-4 or 1111:222::/64.

    This supports a much wider range of address string formats than InetAddress.getByName. It supports subnet formats, provides specific error messages, and allows more specific configuration.

    You can control all of the supported formats using IPAddressStringParameters.Builder to build a parameters instance of IPAddressStringParameters. When not using the constructor that takes a IPAddressStringParameters, a default instance of IPAddressStringParameters is used that is generally permissive.

    Supported formats

    Both IPv4 and IPv6 are supported.

    Subnets are supported:

    • wildcards '*' and ranges '-' (for example 1.*.2-3.4), useful for working with subnets
    • SQL wildcards '%' and '_', although '%' is considered an SQL wildcard only when it is not considered an IPv6 zone indicator
    • CIDR network prefix length addresses, like 1.2.3.4/16, which is equivalent to 1.2.*.*
    • address/mask pairs, in which the mask is applied to the address, like 1.2.3.4/255.255.0.0, which is also equivalent to 1.2.*.*

    You can combine these variations, such as 1.*.2-3.4/255.255.255.0

    IPv6 is fully supported:

    • IPv6 addresses like ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
    • IPv6 zones or scope ids, like ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%zone
    • IPv6 mixed addresses are supported, which are addresses for which the last two IPv6 segments are represented as IPv4, like ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255
    • IPv6 compressed addresses like ::1
    • A single value of 32 hex digits like 00aa00bb00cc00dd00ee00ff00aa00bb with or without a preceding hex delimiter 0x
    • A base 85 address comprising 20 base 85 digits like 4)+k&C#VzJ4br>0wv%Yp as in rfc 1924 https://tools.ietf.org/html/rfc1924

    All of the above subnet variations work for IPv6, whether network prefixes, masks, ranges or wildcards. Similarly, all the the above subnet variations work for any supported IPv4 format, such as the standard dotted-decimal IPv4 format as well as the inet_aton formats listed below.

    This class support all address formats of the C routine inet_pton and the Java method java.net.InetAddress.getByName. This class supports all IPv4 address formats of the C routine inet_aton as follows:

    • IPv4 hex: 0x1.0x2.0x3.0x4 (0x prefix)
    • IPv4 octal: 01.02.03.0234. Note this clashes with the same address interpreted as dotted decimal
    • 3-part IPv4: 1.2.3 (which is interpreted as 1.2.0.3 (ie the third part covers the last two)
    • 2-part IPv4: 1.2 (which is interpreted as 1.0.0.2 (ie the 2nd part covers the last 3)
    • 1-part IPv4: 1 (which is interpreted as 0.0.0.1 (ie the number represents all 4 segments, and can be any number of digits less than the 32 digits which would be interpreted as IPv6)
    • hex or octal variants of 1, 2, and 3 part, such as 0xffffffff (which is interpreted as 255.255.255.255)

    inet_aton (and this class) allows mixing octal, hex and decimal (e.g. 0xa.11.013.11 which is equivalent to 11.11.11.11). String variations using prefixes, masks, ranges, and wildcards also work for inet_aton style.

    Note that there is ambiguity when supporting both inet_aton octal and dotted-decimal leading zeros, like 010.010.010.010 which can be interpreted as octal or decimal, thus it can be either 8.8.8.8 or 10.10.10.10, with the default behaviour using the former interpretation

    This behaviour can be controlled by IPAddressStringParameters.Builder.getIPv4AddressParametersBuilder() and IPv4AddressStringParameters.Builder.allowLeadingZeros(boolean)

    Some additional formats:

    • null or empty strings are interpreted as the loopback, in the same way as InetAddress.getByName interprets null or empty strings
    • the single wildcard address "*" which represents all addresses both ipv4 and ipv6, although you need to give it some help when converting to IPAddress
    • specifying CIDR prefix lengths with no corresponding addresses are interpreted as the corresponding network mask. For instance, /64 is interpreted as the 64 bit network mask (ie 64 ones followed by 64 zeros)

    If you have an address in which segments have been delimited with commas, such as "1,2.3.4,5.6", you can parse this with parseDelimitedSegments(String) which gives an iterator of strings. For "1,2.3.4,5.6" you will iterate through "1.3.4.6", "1.3.5.6", "2.3.4.6" and "2.3.5.6". You can count the number of elements in such an iterator with countDelimitedAddresses(String). Each string can then be used to construct an IPAddressString.

    Usage

    Once you have constructed an IPAddressString object, you can convert it to an IPAddress object with various methods. It is as simple as:
    
     IPAddress address = new IPAddressString("1.2.3.4").getAddress();
     

    If your application takes user input IP addresses, you can validate with:

    
     try {
      IPAddress address = new IPAddressString("1.2.3.4").toAddress();
     } catch(AddressStringException e) {
            //e.getMessage() provides description of validation failure
     }
     
    Most address strings can be converted to an IPAddress object using getAddress() or toAddress(). In most cases the IP version is determined by the string itself.

    There are a few exceptions, cases in which the version is unknown or ambiguous, for which getAddress() returns null:

    • strings which do not represent valid addresses (eg "bla")
    • ambiguous address strings (eg "/32" is a prefix that could be IPv4 or IPv6). For such strings you can provide the IPv4/IPv6 version to #getAddress(IPVersion) to get an address.
    • the "all" address "*" which represents all IPv4 and IPv6 addresses. For this string you can provide the IPv4/IPv6 version to #getAddress(IPVersion) to get an address representing either all IPv4 or all IPv6 addresses.
    • empty string "" is interpreted as the default loopback address. You can provide the ipv4/ipv6 version to#getAddress(IPVersion)to get the loopback version of your choice.

    The other exception is a subnet in which the range of values in a segment of the subnet are not sequential, for which getAddress() throws IncompatibleAddressException because there is no single IPAddress value, there would be many. An IPAddress instance requires that all segments can be represented as a range of values. There are only two unusual circumstances when this can occur:

    • using masks on subnets specified with wildcard or range characters causing non-sequential segments such as the final IPv4 segment of 0.0.0.* with mask 0.0.0.128, this example translating to the two addresses 0.0.0.0 and 0.0.0.128, so the last IPv4 segment cannot be represented as a sequential range of values.
    • using wildcards or range characters in the IPv4 section of an IPv6 mixed address causing non-sequential segments such as the last IPv6 segment of ::ffff:0.0.*.0, this example translating to the addresses ::ffff:0:100, ::ffff:0:200, , ::ffff:0:300, ..., so the last IPv6 segment cannot be represented as a sequential range of values.
    These exceptions do not occur with non-subnets, nor can they occur with standard CIDR prefix-based subnets.

    This class is thread-safe. In fact, IPAddressString objects are immutable. An IPAddressString object represents a single IP address representation that cannot be changed after construction. Some of the derived state is created upon demand and cached, such as the derived IPAddress instances.

    See Also:
    Serialized Form
    Core
    • Constructor Detail

      • IPAddressString

        public IPAddressString(java.lang.String addr)
        Constructs an IPAddressString instance using the given String instance.
        Parameters:
        addr - the address in string format, either IPv4 like a.b.c.d or IPv6 like a:b:c:d:e:f:g:h or a:b:c:d:e:f:h.i.j.k or a::b or some other valid IPv4 or IPv6 form. IPv6 addresses are allowed to terminate with a scope id which starts with a % symbol. Both types of addresses can terminate with a network prefix value like a.b.c.d/24 or ::/24 Optionally, you can specify just a network prefix value like /24, which represents the associated masks 255.255.255.0/24 or ffff:ff00::/24.

        Both IPv4 and IPv6 addresses can terminate with a mask instead of a prefix length, like a.b.c.d/255.0.0.0 or ::/ffff:: If a terminating mask is equivalent to a network prefix, then it will be the same as specifying the prefix, so a.b.c.d/16 is the same as a.b.c.d/255.255.0.0 If a terminating mask is not equivalent to a network prefix, then the mask will simply be applied to the address to produce a single address.

        You can also alter the addresses to include ranges using the wildcards * and -, such as 1.*.1-2.3.

      • IPAddressString

        public IPAddressString(java.lang.String addr,
                               IPAddressStringParameters valOptions)
        Parameters:
        addr - the address in string format This constructor allows you to alter the default validation options.
    • Method Detail

      • isPrefixed

        public boolean isPrefixed()
        Returns:
        whether this address has an associated prefix length
      • getNetworkPrefixLength

        public java.lang.Integer getNetworkPrefixLength()
        Returns:
        if this address is a valid address with a network prefix then this returns that prefix, otherwise returns null
      • isValid

        public boolean isValid()
        Returns:
        whether the address represents one of the accepted IP address types, which are: an IPv4 address, an IPv6 address, a network prefix, the address representing all addresses of all types, or an empty string. If it does not, and you want more details, call validate() and examine the thrown exception.
      • isIPAddress

        public boolean isIPAddress()
        Returns:
        whether the address represents a valid specific IP address, as opposed to an empty string, the address representing all addresses of all types, a prefix length, or an invalid format.
      • isAllAddresses

        public boolean isAllAddresses()
        Returns:
        whether the address represents the set all all valid IP addresses (as opposed to an empty string, a specific address, a prefix length, or an invalid format).
      • isPrefixOnly

        public boolean isPrefixOnly()
        Returns:
        whether the address represents a valid IP address network prefix (as opposed to an empty string, an address with or without a prefix, or an invalid format).
      • isEmpty

        public boolean isEmpty()
        Returns true if the address is empty (zero-length).
        Returns:
      • isIPv4

        public boolean isIPv4()
        Returns true if the address is IPv4 (with or without a network prefix, with or without wildcard segments).
        Returns:
      • isIPv6

        public boolean isIPv6()
        Returns true if the address is IPv6 (with or without a network prefix, with or without wildcard segments).
        Returns:
      • isMixedIPv6

        public boolean isMixedIPv6()
        If this address string represents an IPv6 address, returns whether the lower 4 bytes were represented as IPv4
        Returns:
      • isBase85IPv6

        public boolean isBase85IPv6()
        If this address string represents an IPv6 address, returns whether the string was base 85
        Returns:
      • isLoopback

        public boolean isLoopback()
        See Also:
        InetAddress.isLoopbackAddress()
      • isZero

        public boolean isZero()
      • validateIPv4

        public void validateIPv4()
                          throws AddressStringException
        Validates that this string is a valid IPv4 address, and if not, throws an exception with a descriptive message indicating why it is not.
        Throws:
        AddressStringException
      • validateIPv6

        public void validateIPv6()
                          throws AddressStringException
        Validates that this string is a valid IPv6 address, and if not, throws an exception with a descriptive message indicating why it is not.
        Throws:
        AddressStringException
      • validateNetworkPrefixLength

        public static int validateNetworkPrefixLength(IPAddress.IPVersion ipVersion,
                                                      java.lang.CharSequence networkPrefixLength)
                                               throws PrefixLenException
        Validates that the string has the format "/x" for a valid prefix length x.
        Parameters:
        ipVersion - IPv4, IPv6, or null if you do not know in which case it will be assumed that it can be either
        networkPrefixLength - the network prefix length integer as a string, eg "24"
        Returns:
        the network prefix length
        Throws:
        IncompatibleAddressException - if invalid with an appropriate message
        PrefixLenException
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class java.lang.Object
      • equals

        public boolean equals(java.lang.Object o)
        Two IPAddressString objects are equal if they represent the same set of addresses. Whether one or the other has an associated network prefix length is not considered. If an IPAddressString is invalid, it is equal to another address only if the other address was constructed from the same string.
        Overrides:
        equals in class java.lang.Object
      • getHostAddress

        public IPAddress getHostAddress()
        If this address string was constructed from a host address with prefix length, then this provides just the host address, rather than the address provided by getAddress() that incorporates the prefix.

        Otherwise this returns the same object as getAddress().

        This method returns null for invalid formats, the equivalent method toHostAddress() throws exceptions for invalid formats.

        Returns:
        See Also:
        AddressNetwork.getPrefixConfiguration()
      • getAddress

        public IPAddress getAddress(IPAddress.IPVersion version)
        Similar to #toAddress(IPVersion), but returns null rather than throwing an exception with the address is invalid or does not match the supplied version.
      • getAddress

        public IPAddress getAddress()
        If this represents an ip address, returns that address. Otherwise, returns null.

        This method will return null for invalid formats. Use toAddress() for an equivalent method that throws exceptions for invalid formats.

        If you have a prefix address and you wish to get only the host without the prefix, use getHostAddress()

        Specified by:
        getAddress in interface HostIdentifierString
        Returns:
        the address
      • toAddress

        public IPAddress toAddress(IPAddress.IPVersion version)
                            throws AddressStringException,
                                   IncompatibleAddressException
        Produces the IPAddress of the specified address version corresponding to this IPAddressString.

        In most cases the string indicates the address version and calling toAddress() is sufficient, with a few exceptions.

        When this object represents only a network prefix length, specifying the address version allows the conversion to take place to the associated mask for that prefix length.

        When this object represents all addresses, specifying the address version allows the conversion to take place to the associated representation of all IPv4 or all IPv6 addresses.

        When this object represents the empty string and that string is interpreted as a loopback, then it returns the corresponding loopback address. If empty strings are not interpreted as loopback, null is returned.

        When this object represents an ipv4 or ipv6 address, it returns that address if and only if that address matches the provided version.

        If the string used to construct this object is an invalid format, or a format that does not match the provided version, then this method throws AddressStringException.

        Parameters:
        version - the address version that this address should represent.
        Returns:
        Throws:
        AddressStringException
        IncompatibleAddressException - address in proper format cannot be converted to an address: for masks inconsistent with associated address range, or ipv4 mixed segments that cannot be joined into ipv6 segments
      • toAddress

        public IPAddress toAddress()
                            throws AddressStringException,
                                   IncompatibleAddressException
        Produces the IPAddress corresponding to this IPAddressString.

        If this object does not represent a specific IPAddress or a ranged IPAddress, null is returned, which may be the case if this object represents only a network prefix or if it represents the empty address string.

        If the string used to construct this object is not a known format (empty string, address, range of addresses, or prefix) then this method throws AddressStringException.

        An equivalent method that does not throw exception for invalid formats is getAddress()

        If you have a prefixed address and you wish to get only the host rather than the address with the prefix, use toHostAddress()

        As long as this object represents a valid address (but not necessarily a specific address), this method does not throw.

        Specified by:
        toAddress in interface HostIdentifierString
        Throws:
        AddressStringException - if the address format is invalid
        IncompatibleAddressException - if a valid address string representing multiple addresses cannot be represented This happens only for masks inconsistent with the associated address ranges, or ranges in ipv4 mixed segments that cannot be joined into ipv6 segments
      • adjustPrefixBySegment

        public IPAddressString adjustPrefixBySegment(boolean nextSegment)
      • adjustPrefixLength

        public IPAddressString adjustPrefixLength(int adjustment)
      • countDelimitedAddresses

        public static int countDelimitedAddresses(java.lang.String str)
        Given a string with comma delimiters to denote segment elements, this method will count the possible combinations.

        For example, given "1,2.3.4,5.6" this method will return 4 for the possible combinations: "1.3.4.6", "1.3.5.6", "2.3.4.6" and "2.3.5.6"

        Parameters:
        str -
        Returns:
      • parseDelimitedSegments

        public static java.util.Iterator<java.lang.String> parseDelimitedSegments(java.lang.String str)
        Given a string with comma delimiters to denote segment elements, this method will provide an iterator to iterate through the possible combinations.

        For example, given "1,2.3.4,5.6" this will iterate through "1.3.4.6", "1.3.5.6", "2.3.4.6" and "2.3.5.6"

        Another example: "1-2,3.4.5.6" will iterate through "1-2.4.5.6" and "1-3.4.5.6".

        This method will not validate strings. Each string produced can be validated using an instance of IPAddressString.

        Parameters:
        str -
        Returns:
      • convertToPrefixLength

        public java.lang.String convertToPrefixLength()
                                               throws AddressStringException
        Converts this address to a prefix length
        Returns:
        the prefix of the indicated IP type represented by this address or null if this address is valid but cannot be represented by a network prefix length
        Throws:
        AddressStringException - if the address is invalid
      • toNormalizedString

        public java.lang.String toNormalizedString()
        Description copied from interface: HostIdentifierString
        provides a normalized String representation for the host identified by this HostIdentifierString instance
        Specified by:
        toNormalizedString in interface HostIdentifierString
        Returns:
        the normalized string
      • toString

        public java.lang.String toString()
        Gives us the original string provided to the constructor. For variations, call getAddress()/toAddress() and then use string methods on the address object.
        Overrides:
        toString in class java.lang.Object