import ipaddress import subprocess import re # 执行windows命令 def exec_command(commands) -> list: """执行windows命令""" if not commands: return list() # 子进程的标准输出设置为管道对象 if isinstance(commands, str): commands = [commands] return_list = [] for i in commands: p = subprocess.Popen(i, shell=True, stdout=subprocess.PIPE, universal_newlines=True) p.wait() res = "".join(p.stdout.readlines()) return_list.append(res) return return_list def get_net_card(): """ 功能:通过ipconfig返回的文本解析网卡名字、ip、掩码、网关等信息 注释:简单做了注释 测试:在window10 专业版测试通过(可以检测到以太网两个(包含手机、网线)、wifi一个) 测试反馈:如果使用发现其余问题可以反馈到 sunnylishaoxu@163.com,非常感谢 说明一: 默认网关. . . . . . . . . . . . . : fe80::10b1:1865:86e8:ad10%41 172.20.10.1 """ net_card_data = list() res = exec_command("ipconfig") temp_dict = dict(flag=True) gateway_error = False for x in res[0].splitlines(): try: # 匹配IP正则 pattern = re.compile(r'((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}') # 测试发现有的网关会默认在下一行,情况见说明一,所以这边检查到默认网关,发现没有匹配到,则从下一行找 if gateway_error: temp_dict['gateway1'] = pattern.search(x).group() gateway_error = False #print("当前网卡 %s 获取第二行网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1'])) continue # 如果发现新的适配器,则重置上一个网卡是否可用的状态 if "适配器" in x: temp_dict = dict(flag=True) temp_dict['card_name'] = x.split(" ", 1)[1][:-1] #print("当前网卡 %s" % (temp_dict['card_name'])) continue if "IPv4 地址" in x: temp_dict['ip'] = pattern.search(x).group() #print("当前网卡 %s 获取IP信息 %s" % (temp_dict['card_name'], temp_dict['ip'])) continue elif "子网掩码" in x: temp_dict['mask'] = pattern.search(x).group() #print("当前网卡 %s 获取子网掩码信息 %s" % (temp_dict['card_name'], temp_dict['mask'])) continue # 测试发现有的网关会默认在下一行,情况见说明一,所以这边做了异常处理 elif "默认网关" in x: try: temp_dict['gateway1'] = pattern.search(x).group() #print("当前网卡 %s 获取默认网关信息 %s" % (temp_dict['card_name'], temp_dict['gateway1'])) except: gateway_error = True #print("当前网卡 %s 解析当前行默认网关信息错误" % (temp_dict['card_name'])) # 如果检查到网关,代表当前适配器信息已经获取完毕 重置网关状态与适配器信息字典 if temp_dict.get("gateway1"): net_card_data.append(temp_dict) #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict)) temp_dict = dict(flag=True) continue # 发现媒体已断开则更改当前适配器状态 elif "媒体已断开" in x: #print("当前网卡 %s 已断开 跳过\n\n" % (temp_dict['card_name'])) temp_dict['flag'] = False continue # 判断媒体状态正常,IP、子网掩码、网关都正常后,保持起来 if temp_dict.get("flag") and temp_dict.get("ip") and temp_dict.get("mask") and temp_dict.get("gateway1"): #print("当前网卡 %s 当前适配器信息获取完毕 %s \n\n" % (temp_dict['card_name'], temp_dict)) net_card_data.append(temp_dict) # 重置网关状态与适配器信息字典 temp_dict = dict(flag=True) continue except Exception as e: # print(e) # print(x) pass # for i in net_card_data: # print("%s:%s" % (i.get("card_name"), i)) return net_card_data # 子网掩码地址转长度 def netmask_to_bit_length(netmask): """ >>> netmask_to_bit_length('255.255.255.0') 24 >>> """ # 分割字符串格式的子网掩码为四段列表 # 计算二进制字符串中 '1' 的个数 # 转换各段子网掩码为二进制, 计算十进制 return sum([bin(int(i)).count('1') for i in netmask.split('.')]) # 子网掩码长度转地址 def bit_length_to_netmask(mask_int): """ >>> bit_length_to_netmask(24) '255.255.255.0' >>> """ bin_array = ["1"] * mask_int + ["0"] * (32 - mask_int) tmpmask = [''.join(bin_array[i * 8:i * 8 + 8]) for i in range(4)] tmpmask = [str(int(netmask, 2)) for netmask in tmpmask] return '.'.join(tmpmask) def getStartIP(gateway:str,mask:str): gatewayList = gateway.split('.') maskList = mask.split('.') newStartIP='' for i in range(4): bgate = list(bin(int(gatewayList[i])).replace('0b','').zfill(8)) bmask = list(bin(int(maskList[i])).replace('0b','').zfill(8)) # print('gate:{}'.format(bgate)) # print('mask:{}'.format(bmask)) ngate = [0, 0, 0, 0, 0, 0, 0, 0] for n in range(8): if bmask[n]=='0': ngate[n]=0 else: ngate[n]=bgate[n] # print("newGate:{}".format(ngate)) nbgate = '' for item in ngate: nbgate+=str(item) # print(nbgate) # print('formate gate:{}'.format(int(nbgate, 2))) newStartIP += str(int(nbgate, 2)) newStartIP += '.' # print(gatewayList) # print(newStartIP[:-1]) return newStartIP[:-1] def ipFind(): res = get_net_card() #print(res) allNetIP = [] for i in res: ip = i['gateway1'] ipl = ip.split('.') mask = i['mask'] print(mask) newip = getStartIP(ip, mask) masklen = netmask_to_bit_length(mask) net = ipaddress.ip_network('{}/{}'.format(newip, masklen)) for x in net.hosts(): allNetIP.append(str(x)) return allNetIP if __name__ == '__main__': allNetIP = ipFind() print(allNetIP)