Is there a specific data type for storing IP addresses in Java? I have one specific functionality requirement:
I know of java.net.inetaddress
but I believe it doesn't give me this functionality. Any ideas?
I would use java.net.InetAddress
or one of its subclasses and write a custom comparator plus a range class:
One downside of InetAddress is that getByName
results in a DNS access. You might want to look at Guava's com.google.common.net.InetAddresses
helper class if you want to avoid the penalty for DNS.
public enum InetAddressComparator implements Comparator<InetAddress> {
INSTANCE;
public int compare(InetAddress first, InetAddress second) {
byte[] firstBytes = first.getAddress();
byte[] secondBytes = second.getAddress();
if (firstBytes.length != secondBytes.length) {
throw new IllegalArgumentException("Cannot compare IPv4 and IPv6 addresses");
}
// getAddress returns bytes in network byte order:
// the least significant byte is at the last index
for (int i = firstBytes.length - 1; i >= 0; i--) {
// translate the byte to an int with only the last 8 bits set,
// effectively treating it as unsigned
int a = firstBytes[i] & 0xff;
int b = secondBytes[i] & 0xff;
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
}
return 0;
}
}
public class Range<T> {
private T lower;
private T upper;
private Comparator<T> comparator;
public Range(T lower, T upper, Comparator<T> comparator) {
if (comparator.compare(lower, upper) <= 0) {
this.lower = lower;
this.upper = upper;
} else {
this.lower = upper;
this.upper = lower;
}
this.comparator = comparator;
}
public boolean contains(T element) {
return comparator.compare(lower, element) <= 0 &&
comparator.compare(upper, element) >= 0;
}
}
public class Main {
public static void main(String[] args) throws Exception {
InetAddress start = InetAddress.getByName("10.10.10.1");
InetAddress end = InetAddress.getByName("10.10.11.255");
InetAddress test = InetAddress.getByName("10.10.10.192");
assert InetAddressComparator.INSTANCE.compare(start, test) == -1;
assert InetAddressComparator.INSTANCE.compare(end, test) == 1;
assert InetAddressComparator.INSTANCE.compare(test, test) == 0;
assert new Range<InetAddress>(start, end, InetAddressComparator.INSTANCE)
.contains(test);
}
}
An IP (IPv4) is 32 bits (the same size as an int in Java). Since you want to do comparisons using unsigned ints (if you need to support IP's above 128.0.0.0) you need to use longs instead.
10.10.10.1 is: (10 << 24) + (10 << 16) + (10 << 8) + 1 = 168430081
10.10.11.255 is: (10 << 24) + (10 << 16) + (11 << 8) + 255 = 168430591
10.10.10.192 is: (10 << 24) + (10 << 16) + (10 << 8) + 192 = 168430272
Since 168430081 <= 168430272 && 168430272 <= 168430591
, (In other words 168430272 is between 168430081 and 168430272) your IP is in the range.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With