算法与设计模式系列2之实现子网掩码的从数字到常用格式的转换
preface
因为linux系统信息采集的需要,需要把数字类型的掩码转换为255.255.0.0这样的格式,尽管python官网提供了IPy这样的模块可以处理这样的事情,,但是本人懒得安装了,所以自己写了 一个算法来做,有兴趣的同学可以参考下。目前还未测试出bug,如果有问题请随时联系本人邮箱18500777133@sina.cn
Python版本
def calc_netmask(netmask):
'''
计算子网掩码,由数字类型转为xx.xxx.xx.xx
算法是这样的: 得到的数字先除以8,得到的商就是有多少个255,余数就需要再计算,余数等于1,那么最后一位子网眼码就是2**(8-1),8是一段子网眼码长度,
为8个1,1111111,二进制计算。最后一段眼码计算方式如下:
余数为1,即2**7,
余数为2,即2**7+2**6
余数为3,即2**7+2**6+2**5
依次类推
:param netmask:
:return:
'''
if isinstance(netmask,int):
factor,remainder =netmask.__divmod__(8)
mi = 8 - remainder # 计算这个数字的幂
last_mask = 0
while mi <= 7: # 判断掩码长度是否超过了7,超过了长度跳出循环,因为掩码的长度最多是8.
last_mask = 2**mi + last_mask
mi=mi+1
if factor == 1 and last_mask == 0 : # 意味着是8位的子网掩码
return_netmask = "%s%s"%(factor*'255.','0.0.0')
elif (factor == 1 and last_mask != 0 ) : #意味着8-24之间的子网掩码
last_mask = '%s.'%last_mask
return_netmask = "%s%s%s"%(factor*'255.',last_mask,'0.0')
elif (factor == 2 and last_mask == 0): #意味着16位整的子网掩码
return_netmask = "%s0.0"%(factor*'255.')
elif( factor == 3 and last_mask == 0 ): # 意味着24位整的掩码
return_netmask = "%s%s"%(factor*'255.','0')
elif( factor == 3 and last_mask != 0 ): #意味着24-32之间的子网掩码
return_netmask = "%s%s"%(factor*'255.',last_mask)
elif (factor == 2 and last_mask != 0): # 意味着16-24位之间子网掩码
return_netmask = "%s%s.%s"%(factor*'255.',last_mask,'0')
elif factor == 4: # 意味着4个255
return_netmask = "%s255"%((factor-1)*'255.')
elif factor == 0: # 小于8位的掩码
return_netmask = "%s.0.0.0"%(last_mask)
return return_netmask
else:
return False
for i in range(0,33):
print(i,calc_netmask(i))
打印结果如下:
第一列数字是掩码的数字,第二列是转换后掩码的格式
0 0.0.0.0
1 128.0.0.0
2 192.0.0.0
3 224.0.0.0
4 240.0.0.0
5 248.0.0.0
6 252.0.0.0
7 254.0.0.0
8 255.0.0.0
9 255.128.0.0
10 255.192.0.0
11 255.224.0.0
12 255.240.0.0
13 255.248.0.0
14 255.252.0.0
15 255.254.0.0
16 255.255.0.0
17 255.255.128.0
18 255.255.192.0
19 255.255.224.0
20 255.255.240.0
21 255.255.248.0
22 255.255.252.0
23 255.255.254.0
24 255.255.255.0
25 255.255.255.128
26 255.255.255.192
27 255.255.255.224
28 255.255.255.240
29 255.255.255.248
30 255.255.255.252
31 255.255.255.254
32 255.255.255.255
go版
import (
"math"
"fmt"
)
func calcNetmask(netmask int) (return_netmask string) {
/*
计算子网掩码,由数字类型转为xx.xxx.xx.xx
算法是这样的: 得到的数字先除以8,得到的商就是有多少个255,余数就需要再计算,余数等于1,那么最后一位子网眼码就是2**(8-1),8是一段子网眼码长度,
为8个1,1111111,二进制计算。最后一段眼码计算方式如下:
余数为1,即2**7,
余数为2,即2**7+2**6
余数为3,即2**7+2**6+2**5
依次类推
:param netmask: tmp netmask
:return:
*/
factor := netmask / 8 // 商
remainder := netmask % 8 // 余数
mi := 8 - remainder // 计算这个数字的幂
var tmp_last_mask float64
for mi <= 7 { // 判断掩码长度是否超过了7,超过了长度跳出循环,因为掩码的长度最多是8.
tmp_last_mask = math.Pow(float64(2), float64(mi)) + tmp_last_mask
mi = mi + 1
}
last_mask := int(tmp_last_mask)
switch {
case factor == 1 && last_mask == 0: // 意味着是8位的子网掩码
return_netmask = fmt.Sprintf("%s%s", addStr(factor, "255."), "0.0.0")
case (factor == 1 && last_mask != 0): //意味着8-24之间的子网掩码
return_netmask = fmt.Sprintf("%s%d.%s", addStr(factor, "255."), last_mask, "0.0")
case (factor == 2 && last_mask == 0): //意味着16位整的子网掩码
return_netmask = fmt.Sprintf("%s0.0", addStr(factor, "255."))
case (factor == 3 && last_mask == 0): // 意味着24位整的掩码
return_netmask = fmt.Sprintf("%s%s", addStr(factor, "255."), "0")
case (factor == 3 && last_mask != 0): // 意味着24-32之间的子网掩码
return_netmask = fmt.Sprintf("%s%d", addStr(factor, "255."), last_mask)
case (factor == 2 && last_mask != 0): // 意味着16-24位之间子网掩码
return_netmask = fmt.Sprintf("%s%d.%s", addStr(factor, "255."), last_mask, "0")
case factor == 4: // 意味着4个255
return_netmask = fmt.Sprintf("%s255", addStr(factor-1, "255."))
case factor == 0: // 小于8位的掩码
return_netmask = fmt.Sprintf("%d.0.0.0", last_mask)
}
return return_netmask
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构