您可以使用子网构建树结构 - 它可以一点一点地构建。这会将检查从 300 减少到最多 32(假设 IPv4),但在大多数情况下要少得多。 (因为它要么在几位之后不匹配,要么在子网掩码的平均长度处匹配)
这是一个简单的二叉树实现。您可能想用一些函数来装饰它,以更常见的"a.b.c.d/e" 格式解析子网。
public class SubnetTree {
private SubnetTree one, zero;
private boolean terminating;
public void addSubnet(int net, int bits) {
if (terminating) {
// If this node is already terminating, then no need to add
// subnets that are more specific
return;
}
if (bits > 0) {
boolean bit = ((net >>> 31) & 1) == 1;
if (bit) {
if (one == null) {
one = new SubnetTree();
}
one.addSubnet(net << 1, bits - 1);
} else {
if (zero == null) {
zero = new SubnetTree();
}
zero.addSubnet(net << 1, bits - 1);
}
} else {
terminating = true;
}
}
public boolean isInRange(int address) {
if (terminating) {
return true;
}
boolean bit = ((address >>> 31) & 1) == 1;
if (bit) {
if (one == null) {
return false;
} else {
return one.isInRange(address << 1);
}
} else {
if (zero == null) {
return false;
} else {
return zero.isInRange(address << 1);
}
}
}
}
对此代码的一个非常简单的测试:
public static void main(String[] args) {
SubnetTree tree = new SubnetTree();
tree.add(Integer.parseUnsignedInt("01100110000000000000000000000000", 2), 8);
System.out.println("true: " + tree.isInRange(Integer.parseUnsignedInt("01100110000000000000100010000101", 2)));
System.out.println("false: " + tree.isInRange(Integer.parseUnsignedInt("01101110000000000000100010000101", 2)));
tree.add(Integer.parseUnsignedInt("01001110000000000000000000000000", 2), 6);
System.out.println("true: " + tree.isInRange(Integer.parseUnsignedInt("01100110000000000000100010000101", 2)));
System.out.println("false: " + tree.isInRange(Integer.parseUnsignedInt("01101110000000000000100010000101", 2)));
System.out.println("true: " + tree.isInRange(Integer.parseUnsignedInt("01001110100000000000000000000000", 2)));
System.out.println("true: " + tree.isInRange(Integer.parseUnsignedInt("01001100100000000000000000111111", 2)));
}