各路大佬们!单 IP, IP 段, CIDR 之间如果做集合运算。

2020-05-22 19:22:23 +08:00
 YahuiAn

用户输入支持如下格式:

10.0.17.35

192.168.1.1/23

www.baidu.com

192.37.3.3-192.168.39.39

现在有一个黑名单功能,也支持如上的形式,想问问这两个集合如何高效的去重呢?

😝

1523 次点击
所在节点    问与答
5 条回复
GeruzoniAnsasu
2020-05-22 19:57:53 +08:00
首先不考虑域名和 url

我当时的实现大概这样

一个 - 指定的范围可以解析成若干个 cidr 或 ip

那现在只需要考虑 cidr 一种情况( ip 可以看做 /32 )
用二叉 trie 来存这些 cidr,在深度为 N 的节点有一个 cidr 对象表示这个 cidr 是 /N

如果某个节点左右子树都存在则递归向上合并节点

插入过程中途遇到某个节点说明这节点已经包含了待插入地址,跳过

然后就没有去重这一说了,匹配就是走这个 trie 跟插入流程几乎一样的

当时没有去重合并完还要导出合并结果的需求
GeruzoniAnsasu
2020-05-22 20:03:26 +08:00
还有一种方式是直接把 ip 地址算成线性空间,每个区间有左右界,合并的时候先按左界排序,然后判断
下一个区间的左界有没有落在前一个区间中,如果在,那么区间右界设成下一个区间右界,如果否,那么第一个区间已处理完毕,可以处理 23 区间
wbrobot
2020-05-22 21:01:35 +08:00
ip2long,然后算数
msg7086
2020-05-23 00:36:50 +08:00
听上去就是个和 trie 差不多的结构。
singerll
2020-05-23 06:43:51 +08:00
转换为 10 进制?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/674491

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX