Sorting IP addresses in Java

Recently I had to sort a list of IP addresses. Sounds simple, but it is a little bit tricky in detail. The problem is, you can’t even sort it by string. Let’s have a look at a little example. You will get something like that:
127.0.0.100
127.0.0.2

That’s completely  unusable for bigger lists of IPs!

To get the correct ordering you have to sort by bytes. Remember: all IP consists of an array of bytes. My solution is to write a Comparator for the InetAddress object, which compares each byte. A little tricky thing was to compare the bytes, because a byte is a signed value.

/**
 * LGPL
 */
public class InetAddressComparator implements Comparator<InetAddress> {
    @Override
    public int compare(InetAddress adr1, InetAddress adr2) {
        byte[] ba1 = adr1.getAddress();
        byte[] ba2 = adr2.getAddress();
 
        // general ordering: ipv4 before ipv6
        if(ba1.length < ba2.length) return -1;
        if(ba1.length > ba2.length) return 1;
 
        // we have 2 ips of the same type, so we have to compare each byte
        for(int i = 0; i < ba1.length; i++) {
            int b1 = unsignedByteToInt(ba1[i]);
            int b2 = unsignedByteToInt(ba2[i]);
            if(b1 == b2)
                continue;
            if(b1 < b2)
                return -1;
            else
                return 1;
        }
        return 0;
    }
 
    private int unsignedByteToInt(byte b) {
        return (int) b & 0xFF;
    }
}

,

  1. #1 by asoftwareguy on 2010/09/15 - 20:41

    Nice solution. You might also want to take a look at a Radix sort, depending on the size of the list of addresses it might perform faster.

  2. #2 by Matze on 2015/05/21 - 17:15

    Hmm, not really sure about. But in my opinion this will not work in every case. You are using bytes for the different octets of the ip address, so your example ip’s will work. But an octet can have 255 as largest and I think you had to use short (-32768 to 32768) instead of byte (only -127 to 127)?!

    For example 192.168.178.1, the 192 should run in an exception, value out of range. Or did I understand something wrong here?

    • #3 by Thilo on 2015/05/26 - 13:21

      Java-Doc:

      The byte data type is an 8-bit signed two’s complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive).

      That’s exactly 255 values!

      And by the way: Check the java-doc of the InetAddress-object. This object is using bytes. 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: