用于存储 IP 地址的数据类型
是否有用于在 Java 中存储 IP 地址的特定数据类型?我有一个特定的功能要求:
- 给定一个 IP 范围和一个 IP,如果它属于该范围,则返回 true,否则返回 false。例如:范围 10.10.10.1-10.10.11.255 和 IP 10.10.10.192 应返回 true。
我知道,但我相信它不会给我这个功能。有什么想法吗?java.net.inetaddress
是否有用于在 Java 中存储 IP 地址的特定数据类型?我有一个特定的功能要求:
我知道,但我相信它不会给我这个功能。有什么想法吗?java.net.inetaddress
我会使用或其子类之一,并编写一个自定义比较器和一个范围类:java.net.InetAddress
InetAddress的一个缺点是导致DNS访问。如果你想避免DNS的惩罚,你可能想看看番石榴的助手类。getByName
com.google.common.net.InetAddresses
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);
}
}
IP (IPv4) 为 32 位(与 Java 中的 int 大小相同)。由于您希望使用无符号整数进行比较(如果您需要支持高于 128.0.0.0 的 IP),因此您需要改用 long。
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
由于 ,(换句话说168430272介于 168430081 和 168430272 之间),因此您的 IP 在范围内。168430081 <= 168430272 && 168430272 <= 168430591