一开始打开github,一看是.net代码,一脸懵。第二天起来于心不甘,就想试试能不能根据代码逻辑以及函数名称分析一波算法。于是做了一波曲折但有趣的研究。现在将工具分享出来,希望能帮到大家,特别是需要处理大批量IP段或者内网时。其中研究的过程也可供各位师傅茶余饭后”取个乐子”。
二、工具介绍
三、什么是区间合并github地址:https://github.com/foryujian/ipintervalmerge
功能:上面的图片中冰尘师傅已经说的很清楚了,不再多言。
(引自御剑师傅的github)
192.168.0.0/24192.168.24.0/22192.168.1.3-192.168.1.5192.168.1.2-192.168.1.6192.168.1.1
IP合并区间就是把重叠的IP段进行扩充,比如以上结果经过合并处理后变成:
四、各部分功能浅析192.168.0.0-192.168.0.255192.168.1.1192.168.1.2-192.168.1.6192.168.24.0-192.168.27.255
4.1 读取文件中的IP地址类型 For Each txt In IO.File.ReadLines(file) ... If txt.Contains("-") Then ... ElseIf txt.Contains("/") Then ... Else ... End If Next首先说明一点,我不懂VB.NET,在寻求各方的“支援”无果后,就自行按照单词的本身含义+百度来理解的代码,其中如有错误,请各位师傅不吝赐教。其次,这个浅析针对的是,而不是 。这两个的算法是有差别的,我会在后文中给出。
CIDR形式:192.168.0.0/24
包含分隔符形式:192.168.1.2-192.168.1.6
单个IP形式:192.168.1.1
将点分十进制格式表示的IP转换成二进制形式表示的IP
算法描述:
先将点分十进制格式表示的IP以.来分成4部分。(e.g.:192.168.1.2 —>>192、168、1、2) 第一段左移24位,第二段左移16位,第三段左移8位,第四段原样保留。(e.g.:(192<<24)+(168<<16)+(1<<8)+2即二进制形式表示的IP)
4.3 处理文件中的IP区间
intervals存放处理结果。
CIDR形式的处理:
tmp = txt.Split("/") If tmp.Length = 2 Then Dim ip1 As String = tmp(0) Dim ip2 As String = tmp(1) tmp = ip1.Split(".") For x As Integer = 0 To 3 ip(x) = Integer.Parse(tmp(x)) tmp(x) = Convert.ToString(ip(x), 2).PadLeft(8, "0") Next Dim BitString As String = String.Join("", tmp) BitString = BitString.Substring(0, CInt(ip2)).PadRight(32, "1") i = 0 For x As Integer = 0 To 31 Step 8 tmp(i) = BitString.Substring(x, 8) ip(i) = Convert.ToInt32(tmp(i), 2) i += 1 Next ip2 = String.Join(".", ip) st = IpToLong(ip1) ed = IpToLong(ip2) intervals.Add(New Interval(st, ed)) End If
算法描述:
以”/”将CIDR形式表示的IP地址分隔成两部分:tmp[0],tmp[1]。
将第一部分的IP地址以”.”分成4部分。
每一部分表示成8位二进制形式,不足的左边用0填充。然后将这4个部分连接起来。
将连接后的字符串从开始处截取tmp[1]长度的子串,然后在右边用1填充至32位。
在intervals中添加tmp[0]的二进制表示形式(即调用IpToLong函数)和第4步中的处理结果。(e.g.:192.168.0.0/24 —>>intervals中会添加”11000000101010000000000000000000″和”11000000101010000000000011111111″)
包含分隔符形式的处理:
tmp = txt.Split("-") If tmp.Length = 2 Then st = IpToLong(tmp(0)) ed = IpToLong(tmp(1)) intervals.Add(New Interval(st, ed)) End If