Question

So you have a String that is retrieved from an admin web UI (so it is definitely a String). How can you find out whether this string is an IP address or a hostname in Java?

Update: I think I didn't make myself clear, I was more asking if there is anything in the Java SDK that I can use to distinguish between IPs and hostnames? Sorry for the confusion and thanks for everybody who took/will take the time to answer this.

Was it helpful?

Solution

You can use a regular expression with this pattern:

\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

That will tell you if it's an IPv4 address.

OTHER TIPS

Do we get to make the assumption that it is one or the other, and not something completely different? If so, I'd probably use a regex to see if it matched the "dotted quad" format.

You can see if the string matches the number.number.number.number format, for example:

\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b

will match anything from 0 - 999.

Anything else you can have it default to hostname.

URI validator = new URI(yourString);

That code will validate the IP address or Hostname. (It throws a malformed URI Exception if the string is invalid)

If you are trying to distinguish the two..then I miss read your question.

Couldn't you just to a regexp match on it?

You can use a security manager with the InetAddress.getByName(addr) call.

If the addr is not a dotted quad, getByName will attempt to perform a connect to do the name lookup, which the security manager can capture as a checkConnect(addr, -1) call, resulting in a thrown SecurityException that you can catch.

You can use System.setSecurityManager() if you're running fully privileged to insert your custom security manager before the getByName call is made.

It is not as simple as it may appear, there are some ambiguities around characters like hyphens, underscore, and square brackets '-', '_', '[]'.

The Java SDK is has some limitations in this area. When using InetAddress.getByName it will go out onto the network to do a DNS name resolution and resolve the address, which is expensive and unnecessary if all you want is to detect host vs address. Also, if an address is written in a slightly different but valid format (common in IPv6) doing a string comparison on the results of InetAddress.getByName will not work.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top