仅使用Python 2.7内置模块计算子网中的所有IP

仅使用Python 2.7内置模块计算子网中的所有IP,python,python-2.7,ip,subnet,cidr,Python,Python 2.7,Ip,Subnet,Cidr,我想知道如何创建一个采用cidr符号的脚本,如下所示: 204.15.20.0/22 并计算该范围内所有可能的IP地址 204.15.20.0 ... ... 204.15.23.255 现在我终于知道了这背后的数学原理,我想知道如何用python制作这样一个模块 我知道一些现成的模块,如netaddr.IPNetwork(),但我想知道如何做到这一点,只使用Python 2.7中的内置模块 谢谢:)您可以使用socket和struct模块组合在IPv4地址和整数之间进行转换。在此之后,问题

我想知道如何创建一个采用cidr符号的脚本,如下所示:

204.15.20.0/22
并计算该范围内所有可能的IP地址

204.15.20.0
...
...
204.15.23.255
现在我终于知道了这背后的数学原理,我想知道如何用python制作这样一个模块

我知道一些现成的模块,如netaddr.IPNetwork(),但我想知道如何做到这一点,只使用Python 2.7中的内置模块


谢谢:)

您可以使用
socket
struct
模块组合在IPv4地址和整数之间进行转换。在此之后,问题是屏蔽整数地址,并根据cidr值计算出子网中的值范围

import re
import socket
import struct

def inet_atoi(ipv4_str):
    """Convert dotted ipv4 string to int"""
    # note: use socket for packed binary then struct to unpack
    return struct.unpack("!I", socket.inet_aton(ipv4_str))[0]

def inet_itoa(ipv4_int):
    """Convert int to dotted ipv4 string"""
    # note: use struct to pack then socket to string
    return socket.inet_ntoa(struct.pack("!I", ipv4_int))

def ipv4_range(ipaddr):
    """Return a list of IPv4 address contianed in a cidr address range"""
    # split out for example 192.168.1.1:22/24
    ipv4_str, port_str, cidr_str = re.match(
        r'([\d\.]+)(:\d+)?(/\d+)?', ipaddr).groups()

    # convert as needed
    ipv4_int = inet_atoi(ipv4_str)
    port_str = port_str or ''
    cidr_str = cidr_str or ''
    cidr_int = int(cidr_str[1:]) if cidr_str else 0

    # mask ipv4
    ipv4_base = ipv4_int & (0xffffffff << (32 - cidr_int))

    # generate list
    addrs = [inet_itoa(ipv4_base + val)
        for val in range(1 << (32 - cidr_int) + 2)]
    return addrs

print(ipv4_range('204.15.20.0/22'))
重新导入
导入套接字
导入结构
def inet_atoi(ipv4_str):
“”“将虚线ipv4字符串转换为int”“”
#注意:使用套接字进行打包二进制文件,然后使用struct进行解包
返回结构解包(“!I”,socket.inet\u aton(ipv4\u str))[0]
def inet_itoa(ipv4_int):
“”“将int转换为虚线ipv4字符串”“”
#注意:使用struct进行打包,然后使用socket进行字符串转换
返回socket.inet\u ntoa(结构包(“!I”,ipv4\u int))
def ipv4_范围(ipaddr):
“”“返回包含在cidr地址范围内的IPv4地址列表”“”
#例如,拆分为192.168.1.1:22/24
ipv4\u str、端口\u str、cidr\u str=re.match(
r'([\d\.]+)(:\d+)(/\d+),ipaddr).groups()
#根据需要转换
ipv4\u int=inet\u atoi(ipv4\u str)
端口号=端口号或“”
cidr_str=cidr_str或“”
cidr_int=int(cidr_str[1:]),如果cidr_str为0
#屏蔽ipv4

ipv4\u base=ipv4\u int&(0xffffffff您可以将该地址更改为整数,然后从那里使用
范围
。我不认为它是这样工作的,因为单个八位字节的最大值只能为255(b11111111)@UrielEli不是复制品,我知道它背后的数学原理,正如我在文章中所说的。我想知道如何使用内置模块在Python中实现它。