• 算法与设计模式系列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
    }
    
    
  • 相关阅读:
    第一次用python 写的简单爬虫 记录在自己的博客
    【转】使用notepad运行python
    Android Tools&Cmd
    箴言
    无问西东
    Unity存储路径
    手机屏幕亮度设定
    Go Lang
    iOS .tbd
    Prime31
  • 原文地址:https://www.cnblogs.com/liaojiafa/p/6613983.html
Copyright © 2020-2023  润新知