Java实现IP动态匹配
最近接触了个新的数据结构: Trie 树/ 前缀树/ 字典树 等,都是指的一个意思。想了想,刚好能用来做IP地址的动态匹配,那就实践一下,学以致用。
需求描述
有些时候处于安全考虑,我们需要在系统访问路径或者功能操作上面增加一些权限管控。其中一个比较简单的方案就是IP管控,能不能实现一个简单的动态IP管控呢?
这里只简单的考虑两种用例
- 全字段匹配,192.168.10.1
- 模糊字段匹配,192.168.10.* 或 192.168.*.1
分析设计
全字段匹配其实可以直接equals 比较 就行了,复杂的只要是动态字段匹配。
普通思路分析
用面向对象的思路来整。
可以IP地址切分4段,每个段抽象成一个Class,value表示规则的值,fuzzy表示是否模糊匹配,这样4个段对象就构成了1个IP规则
class Segment{
String value;
boolean fuzzy;
}
class IPRule{
Segment [] segments;
}
然后为了提高效率,可以使用字典结构,将每个规则段的 Value 用 HashMap 缓存起来
HashMap<String, IPRule> firstSegmentMap;
HashMap<String, IPRule> secondSegmentMap;
HashMap<String, IPRule> thirdSegmentMap;
HashMap<String, IPRule> fourthSegmentMap;
然后就是 进行分段匹配,做个筛选
中间可能做一些优化,segment 引用 IPRule 或者 segment 引用下一个Segment,链式结构等等
也能满足需求
前缀树思路分析
这里基本思路和上一小节分析类似,不过这里就用成熟的数据结果—前缀树。
将IP规则按段分成4部分,其中每一部分都可以作为一个节点,那么我们就整成了一个3层的树,类似
基本的结构就是这样的
class IPNode {
String pattern;
String nodeVal;
List<IPNode> childrenNodes;
boolean fuzzy;
抽象两个方法
// 增加IP规则的方法
void addRule(String ipRule);
// 查询具体的IP地址的方法
IPNode search(String ipAddress);
search 基本思路:
- 将IP分4段先从根节点中 开始找 1段 匹配的所有子节点 nodes1
- 然后再从1中的nodes1 中找 2段匹配的 所有子节点 nodes2
- 然后再从2中的nodes2 中找 3段匹配的 所有子节点 nodes3
- 然后再从3中的nodes3 中找 4段匹配的 所有子节点 nodes4
- 找到任意一个就结束
代码实现
这里主要写前缀树的实现
@Data
public class IPNode {
private String pattern; //规则内容
private String nodeValue; //最后段内容
private List<IPNode> childrenNodes; //子节点
private boolean fuzzy;