网络与IP地址计算

1. 关于掩码位

  1. 介绍
  1. 子网掩码都是每段8位2进制,共32位
  2. 子网掩码用来划分局域网的IP地址的,需要和网络地址结合起来使用,计算方法:2^(32-掩码位数)-2
  3. 如常见的24位数掩码:2^(32-24)-2=254
  4. 减去的2代表的时网络地址和广播地址
  1. 广播地址:用于局域网中,给所有这个网段的主机发送数据
  2. 网络地址:用于网络交换

2. 通过掩码位计算子网掩码值

  1. python10进制与2进制之间的转换
# 10进制转2进制
bin(10)
-->0b1010   #注意:0b的b是binary的意思,真实值为1010
# 2进制转10进制
int('11111111',2)
-->255      # 注意第一个参数为带转化的字符串,第二个参数为该参数的进制
  1. python实现掩码位获取子网掩码
def system_change(params):
    if isinstance(params,int) and 32>params:
        bin_data = '1' * params +'0'*(32-params)
        start = 0
        end = 8
        bin_list = []
        while len(bin_data)>=end:
            a = bin_data[start:end]
            start +=8
            end += 8
            b = int(a,2)
            bin_list.append(str(b))
        print('.'.join(bin_list))

3. 通过IP值和子网掩码获取广播地址和网络地址

  1. 计算规则
  1. 取二进制子网掩码前面连续为1的作为值a,长度为len_a
  2. 取二进制IP前面字符串长度为len_a作为值b
  3. 对值a,b进行与运算,得到的值为net_c
  1. a&b
  2. 注意得到的值需以‘0’向右补全长度(即在前面)使其等于len_a
  1. 对net_c向左(即在后面)已‘0’ 补全长度为32,得到的值即为网络地址
  2. 对net_c向左(即在后面)已‘1’ 补全长度为32,得到的值即为广播地址
  1. 将完整二进制IP值切割为含有4个元素的二进制IP列表
def change_bin_ip(bin_info):
    start = 0
    bin_list = []
    while len(bin_info) >= start+8:
        end = start + 8
        a = bin_info[start:end]
        start += 8
        b = int(a, 2)
        bin_list.append(str(b))
    return bin_list
  1. 将完整的IP值转化为4个二进制码的列表
def change_ip_bin(ip):
    ip_list = ip.split('.')
    bin_ip_list = []
    for i in ip_list:
        bin_ip_list.append(bin(int(i)).replace('0b','').rjust(8,'0'))
    # print(bin_ip_list)
    return bin_ip_list
  1. 对比IP地址值和子网掩码值,得到起始网络地址值和广播地址值(十进制的的IP列表)
def rang_of_ip(ip, submask):
    ip_bin_list = change_ip_bin(ip)
    submask_bin_list = change_ip_bin(submask)
    one_index = ''.join(submask_bin_list).find('0')
    # 网络地址,为1的部分
    submask_bin = ''.join(submask_bin_list)[0:one_index]
    # 取IP地址中的相同位数
    ip_bin = ''.join(ip_bin_list)[0:one_index]
    # 进行 与 逻辑运算
    net_int_addr = int(submask_bin, 2) & int(ip_bin, 2)
    # 合并后的网络地址的二进制
    with_bin_net = bin(net_int_addr).replace('0b', '').rjust(one_index, '0')
    # 起始网络地址二进制
    net_bin_addr = change_bin_ip(with_bin_net.ljust(32, '0'))
    # 广播地址二进制
    broad_bin_addr = change_bin_ip(with_bin_net.ljust(32, '1'))
    print(net_bin_addr)
    return net_bin_addr, broad_bin_addr
  1. 根据IP值和掩码位,得出计算结果
def get_range_iplist(ip, mask):
    """
    ip: 输入IP值(字符串)
    mask: 掩码位(整数且在0--30之间)
    """
    if mask >0 and mask <=30:
        # 根据掩码位获取子网掩码 submask
        submask = system_change(mask)
        # a:网络起始值,b: 广播地址值
        network, broadcast = rang_of_ip(ip, submask)
        params_network = copy.deepcopy(network)
        params_broadcast = copy.deepcopy(broadcast)
        params_network[-1] = str(int(params_network[-1]) + 1)
        params_broadcast[-1] = str(int(params_broadcast[-1]) - 1)
        start_ip = params_network
        end_ip = params_broadcast
        ip_count = 2 ** (32 - mask) - 2
        data = {
            'ip_count': ip_count,   # 可生成的IP数
            'submask': submask,     # 掩码
            'network': network,     # 网络位置
            'broadcast': broadcast, # 广播地址
            'start_ip': start_ip,   # 起始IP地址
            'end_ip': end_ip        # 结束IP地址
        }
        return {'msg':'','data':data,'code':'00000'}
    else:
        return {'msg': '掩码位不符合规范:大于0 and 小于等于30', 'data': '', 'code': '00000'}