5

I am using the sun.net.util.IPAddressUtil package to check whether the string contains a valid IPv4 and IPv6 address or not.

Code Snippet is:-

String ipv4addr="200";

    if(IPAddressUtil.isIPv4LiteralAddress(ipv4addr))
    {
        System.out.println("valid ipv4 address");
    }
    else
    {
        System.out.println("not valid");

    }

But for addresses such as 200 and 300 it is still saying it is a valid IPv4 address, which it isn't. When I used the same package and checked for IPV6 address using :-

String ipv6addr="200";

    if(IPAddressUtil.isIPv6LiteralAddress(ipv6addr))
    {
        System.out.println("valid ipv6 address");
    }
    else
    {
        System.out.println("not valid");

    }

I get the correct result. However, IPv4 does not seem to be working or may be I am using it incorrectly. Please guide me. I don't want to use regex for IPv4 validation...

Justine Krejcha
  • 1,235
  • 17
  • 27
AngelsandDemons
  • 2,823
  • 13
  • 47
  • 70
  • 5
    http://www.oracle.com/technetwork/java/faq-sun-packages-142232.html – BalusC Sep 26 '11 at 05:03
  • Yes..I went through this link...But I don't think they have provided any new release for this package or any of the methods mentioned are deprecated...I guess its better to use apache common library for these validations......Any suggestions..? – AngelsandDemons Sep 26 '11 at 10:48
  • possible duplicate of [Validate IP address](http://stackoverflow.com/questions/5667371/validate-ip-address) – Jason C Mar 24 '14 at 16:11

6 Answers6

23

There's a reason you're getting a "valid" result: 200 is a valid IPv4 address.

See, to the computer, an IPv4 address is just a 32-bit number. The dots are entirely for our convenience, because we humans suck at memorizing big precise numbers. But they don't have to be there; there are rules about how an address gets parsed depending on how many parts it has.

When an address consists of one number, it's considered a 32-bit number, and each byte is 8 bits of that number. If you were to parse "200" as an IP address, it would be equivalent to 0.0.0.200. Likewise, "2130706433" would be equivalent to 127.0.0.1.

There are also standards for when an address has two parts like 0.200 (first part is the first byte, and the second part is a 24-bit number representing the other 3 bytes), and even 0.0.200 (first two numbers are bytes, the last part is 16 bits and takes up the other 2 bytes). The "unusual" formats are leftovers from the days of IP address classes, but almost all software that has to parse addresses will understand them. (If you pop open your browser and go to http://1249739112* or even http://74.125.33128*, for example, Google's home page will come up.)

* See the comments for clickable links. Thanks, "link validator". :P

See http://download.oracle.com/javase/6/docs/api/java/net/Inet4Address.html or http://www.perlmonks.org/?node_id=221512, or http://en.wikipedia.org/wiki/IPv4#Address_representations, for some more details.

Java understands these formats as well (as does .net, as well as any decent OS), and parses the address correctly whether it contains 1, 2, 3, or 4 parts.

If you want to check that a would-be address actually looks like "xxx.xxx.xxx.xxx", then you'll probably want to explicitly check that using a pattern, or using a validation library that considers 32-bit numbers as invalid addresses (even though they are valid). I wouldn't bother, though -- if you use the lookup functions provided, you can accept an address in any standard format and it will work.

(All this mess changes with IPv6; there's a much stricter format, and you can't just type in some 36-digit number and expect it to work. But the platform still knows how to parse an address, and you should trust it to do so.)

cHao
  • 84,970
  • 20
  • 145
  • 172
  • It should be noted that the rules for IPv6 addresses are **a lot** stricter. – Joachim Sauer Sep 26 '11 at 06:22
  • @Joachim: Noted. Though, truth be told, i highly doubt too many people are going to be trying to validate IPv6 addresses anytime soon :) – cHao Sep 26 '11 at 06:30
  • which only means that many people are going to be using un-validated IPv6 addresses. They **are** coming and if your software doesn't support them, then you'll be left behind. – Joachim Sauer Sep 26 '11 at 06:34
  • I've been hearing "IPv6 is coming" for >10 years. Still waiting. I can't even get IPV6 to work without a tunnel broker. :P – cHao Sep 26 '11 at 06:48
  • Thanks cHao....I had better be using Apache Validator for checking IPV4 address....I am not keen on using pattern matching and regex.... – AngelsandDemons Sep 26 '11 at 10:45
  • 1
    @chao: Original text: (If you pop open your browser and go to http://1249739112 or even http://74.125.33128, for example, Google's home page will come up.) – cHao Sep 24 '12 at 19:15
3

Check out Guava's InetAddresses class which contains static utility methods for working with IP addresses. (As I understand it uses the sun.net.util.IPAddressUtil class behind the scenes.)

System.out.println(InetAddresses.isInetAddress("400")); // false
Kohányi Róbert
  • 9,791
  • 4
  • 52
  • 81
  • Yes, this works great for IPv4 addresses. However I'd like to accept an Ipv6 address from the command line. For checking IPv6 addresses I can only see the isIsatapAddress(Inet6Address ip) method here. Not sure how to get a Inet6address Object from a String... – Thomas Jun 06 '12 at 15:23
  • @Thomas The code in my answer only *tests* IP addresses. Checkout [this method](http://docs.guava-libraries.googlecode.com/git-history/v12.0/javadoc/com/google/common/net/InetAddresses.html#forString%28java.lang.String%29) instead. – Kohányi Róbert Jun 06 '12 at 16:09
2

It's not a good idea to use internal "sun" packaged classes, I'd try using Apache's Validator

http://commons.apache.org/validator/

which has IP Address validation.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
  • This was the first package I saw while browsing for IPV4 validation.However I was not keen on using it initally.But seems like there is no other option... – AngelsandDemons Sep 26 '11 at 10:46
1

If you want to validate if a string is valid IP address representation, the source code of org.apache.http.conn.util.InetAddressUtils uses these regular expressions:

IPV4_PATTERN = Pattern.compile(
    "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
IPV6_STD_PATTERN = Pattern.compile(
    "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile(
    "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$");
grebulon
  • 7,697
  • 5
  • 42
  • 66
1

That string is an IPv4 string format that was originally introduced by the aton_inet utility in BSD Unix and has persisted until this day in the various Unix and Linux flavours and elsewhere.

https://linux.die.net/man/3/inet_aton

The IPAddress Java library will do validation that can be configured to support aton_inet formats or not. The javadoc is available at the link. Disclaimer: I am the project manager.

Verify if an address is valid, allow inet_aton style:

    String str = "200";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }

Output:

valid address: 0.0.0.200

Verify if an address is valid, do not allow inet_aton style:

    IPAddressStringParameters parameters = new       
      IPAddressStringParameters.Builder().allow_inet_aton(false).toParams();
    addrString = new IPAddressString(str, parameters);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }

Output:

200 IP Address error: options do not allow IPv4 address with less than four segments

Sean F
  • 4,344
  • 16
  • 30
0

After a small research I ended up with something like this

    public static boolean isValidIP4Address(String ipAddress) {
        if (ipAddress.matches("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$")) {
            String[] groups = ipAddress.split("\\.");

            for (int i = 0; i <= 3; i++) {
                String segment = groups[i];
                if (segment == null || segment.length() <= 0) {
                    return false;
                }

                int value = 0;
                try {
                    value = Integer.parseInt(segment);
                } catch (NumberFormatException e) {
                    return false;
                }
                if (value > 255) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

which was fine for simple checks.

Johntor
  • 587
  • 11
  • 26