7

I want to check if a string is a hostname or an ip-address in Java. Is there an API to do it or must I write a parser myself?

The problem is complex because there are IPv4 addresses, short and long IPv6 addresses, short hostnames and FQDN host names.

Gaffi
  • 4,307
  • 8
  • 43
  • 73
Horcrux7
  • 23,758
  • 21
  • 98
  • 156

6 Answers6

6

There doesn't appear to be an API, but writing such function doesn't seem to be very difficult. You can check the following conditions in your code:

  1. If sourceStr contains ":" but no "." -> IPv6
  2. If sourceStr.matches("^.[0-9]{1,3}/..[0-9]{1,3}/..[0-9]{1,3}/..[0-9]{1,3}") == true) -> IPv4
  3. If sourceStr contains "." -> FQDN host name
  4. Otherwise it must be a short hostname
BluesRockAddict
  • 15,525
  • 3
  • 37
  • 35
3

To expand @MrGomez 's answer, Use InetAddresses to validate IP Addresses and InternetDomainName to validate hostnames (FQDN).

Example:

public static boolean validate(final String hostname) {
        return InetAddresses.isUriInetAddress(hostname) || InternetDomainName.isValid(hostname);
    }
GMouaad
  • 69
  • 1
  • 6
2

The IPAddress Java library will do it. The javadoc is available at the link. Disclaimer: I am the project manager.

static void check(HostName host) {
    try {
        host.validate();
        if(host.isAddress()) {
            System.out.println("address: " + host.asAddress());
        } else {
            System.out.println("host name: " + host);
        }
    } catch(HostNameException e) {
        System.out.println(e.getMessage());
    }
}

public static void main(String[] args) {
    HostName host = new HostName("1.2.3.4");
    check(host);
    host = new HostName("1.2.a.4");
    check(host);
    host = new HostName("::1");
    check(host);
    host = new HostName("[::1]");
    check(host);
    host = new HostName("1.2.?.4");
    check(host);  
}

Output:

address: 1.2.3.4
host name: 1.2.a.4
address: ::1
address: ::1
1.2.?.4 Host error: invalid character at index 4
Sean F
  • 4,344
  • 16
  • 30
2

Not possible in JDK API but you can use InetAddresses.forString in google guava which throws exception when argument is not a IP string literal.

Chikei
  • 2,104
  • 1
  • 17
  • 21
2

While you could theoretically write rules to handle these cases yourself, using the usual cadre of RFCs, I'd instead look at the entirety of this class in Google Guava, especially the corner cases, such as how it resolves the embedding of 4-in-6 addresses.

As for determining if you have a FQDN, see if coercion to IP address fails, then try to resolve it against DNS. Anything else should, given your input cases, be a hostname or local resolution that isn't fully qualified.

Kirby
  • 15,127
  • 10
  • 89
  • 104
MrGomez
  • 23,788
  • 45
  • 72
  • 2
    It doesn't look like Guava's class indicates whether a String contains a hostname (non-IP address). – Gili Feb 17 '17 at 02:13
0
import sun.net.util.IPAddressUtil
IPAddressUtil.isIPv4LiteralAddress(addr)
IPAddressUtil.isIPv6LiteralAddress(addr)
milan
  • 2,355
  • 2
  • 23
  • 38
  • 1
    You should edit this to add an explanation for what these commands do, just posting code as a solution isn't helpful. – annedroiid Jul 01 '20 at 14:16
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – Donald Duck Jul 01 '20 at 16:22