gpt4 book ai didi

java - 检查 IP 地址是否在多个可能的子网中

转载 作者:行者123 更新时间:2023-11-30 08:34:10 24 4
gpt4 key购买 nike

我正在解析 Apache 日志并想检查 IP 地址是否属于约 300 个可能的子网列表 ( https://github.com/client9/ipcat)。

  • Internet 流量有很多不同的 IP(我不知道它们属于哪个子网)。
  • 我正在使用 Apache Commons SubnetUtils 包来存储子网。
  • 将 300 个子网中所有可能的 IP 存储在 HashMap 中会占用太多内存。
  • 遍历每个 IP 的每个 SubnetUtil(即使使用之前查找的 HashMap 缓存)非常慢。

还有什么我可以在这里做的吗?

最佳答案

您可以构建一个带有子网的树结构 - 它可以一点一点地构建。这会将检查次数从 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)));
}

关于java - 检查 IP 地址是否在多个可能的子网中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38996895/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com