主页 > 网络编程 > 一款IP区间合并工具及如何使用Python实现相同功能

一款IP区间合并工具及如何使用Python实现相同功能

一开始打开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

四、各部分功能浅析

首先说明一点,我不懂VB.NET,在寻求各方的“支援”无果后,就自行按照单词的本身含义+百度来理解的代码,其中如有错误,请各位师傅不吝赐教。其次,这个浅析针对的是,而不是 。这两个的算法是有差别的,我会在后文中给出。

4.1 读取文件中的IP地址类型 For Each txt In IO.File.ReadLines(file) ... If txt.Contains("-") Then ... ElseIf txt.Contains("/") Then ... Else ... End If Next

CIDR形式:192.168.0.0/24

包含分隔符形式:192.168.1.2-192.168.1.6

单个IP形式:192.168.1.1

4.2 IPToLong Public Shared Function IpToLong(strIP As String) As Long Try Dim ip(3) As Long Dim s As String = strIP.Split(".") ip(0) = Long.Parse(s(0)) ip(1) = Long.Parse(s(1)) ip(2) = Long.Parse(s(2)) ip(3) = Long.Parse(s(3)) Return (ip(0) << 24) + (ip(1) << 16) + (ip(2) << 8) + ip(3) Catch ex As Exception Return 0 End Try End Function

将点分十进制格式表示的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

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!