如何在Python2.x的范围内区分IP地址的范围?

如何在Python2.x的范围内区分IP地址的范围?,python,ip-address,Python,Ip Address,给定IP范围,代码如何从该范围中减去IP地址或IP地址范围 例1: original_range = '10.182.110.0/24' # Same as '10.182.110.0-10.182.110.255' subtract_range = '10.182.110.51-10.182.254' > diff_range = '10.182.110.0-10.182.110.50, 10.182.110.255' 例2: original_range = '10.10.20.0-

给定IP范围,代码如何从该范围中减去IP地址或IP地址范围

例1:

original_range = '10.182.110.0/24'
# Same as '10.182.110.0-10.182.110.255'
subtract_range = '10.182.110.51-10.182.254'
> diff_range = '10.182.110.0-10.182.110.50, 10.182.110.255'
例2:

original_range = '10.10.20.0-10.10.20.20'
subtract_range = '10.10.20.16'
> diff_range = '10.10.20.10-10.10.20.15, 10.10.20.17-10.10.20.20'
例3:

original_range = '10.170.0.0/16'
# Same as '10.170.0.0-10.170.31.255'
subtract_range = '10.170.20.16'
> diff_range = '10.170.0.0-10.170.20.15, 10.170.20.17-10.170.31.255'
谷歌有一个名为address_exclude()的方法。以下是修改自的示例:


以下是我用于执行此操作的函数(在Qualys使用的格式和ipaddr提供的对象实例之间来回移动:

def is_valid_ip_address(address, version=None):
    """ Check validity of address
        Return True if 'address' is a valid ipv4 or ipv6 address.
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False
    try:
        ipaddr.IPAddress(address.strip(),version)
    except ValueError:
        return False
    return True

def is_valid_ipv4_address(address):
    """ Check validity of address
        Return True if 'address' is a valid ipv4 address.
    """
    return is_valid_ip_address(address,4)

def is_valid_ipv6_address(address):
    """ Check validity of address
        Return True if 'address' is a valid ipv6 address.
    """
    return is_valid_ip_address(address,6)

def is_valid_ip_range(iprange, version=None):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ip addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False

    try:
        (start_ip,end_ip) = iprange.split('-')
        start_ip = start_ip.strip()
        end_ip = end_ip.strip()
        if ipaddr.IPAddress(start_ip) == ipaddr.IPAddress(end_ip):
            logging.debug('%s/%s-%s, Error: %s' % (package,module,version,'Start and End IP Address in an IP Range can not be the same IP Address.'))
            return False
        # A valid range requires:
        # 1) The start_ip must be a valid ip address.
        # 2) The end_ip must be a valid ip address.
        # 3) The start_ip must be less than the end_ip.
        # Although socket operations (as are used in qualysconnect.util) are nice, it's not feasible to determine that the start_ip is less than the 
        # end_ip without considerable effort.  We'll use the ipaddr.summarize_address_range function to test all three at one time.
        ipaddr.summarize_address_range(ipaddr.IPAddress(start_ip,version),ipaddr.IPAddress(end_ip,version))
    except ipaddr.AddressValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        return False
    except ValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        return False
    return True

def is_valid_ipv4_range(iprange):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ipv4 addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    return is_valid_ip_range(iprange,4)

def is_valid_ipv6_range(iprange):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ipv4 addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    return is_valid_ip_range(iprange,6)

def cidr_to_ip(cidr,version=None):
    """ Convert an ip address or ip range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('10.0.0.0/24') returns the string '10.0.0.0-10.0.0.255'.
        Returns a String containing an ip address or ip range that can be provided to the Qualys API. 
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False
    try:
        cidr_net = ipaddr.IPNetwork(cidr,version)
    except ValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        raise ValueError, e
    if cidr_net[0] == cidr_net[-1]:
        return str(cidr_net[0])
    iprange = '%s-%s' % (cidr_net[0],cidr_net[-1])
    return iprange

def cidr_to_ipv4(cidr):
    """ Convert an ipv4 address or ipv4 range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('192.0.2.0/24') returns the string '192.0.2.0-192.0.2.255'.
        Returns a String containing an ip address or ip range that can be provided to the Qualys API. 
    """
    return cidr_to_ip(cidr,4)

def cidr_to_ipv6(cidr):
    """ Convert an ipv6 address or ipv6 range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('2001:db8::fff/120') returns the string '2001:db8::f00-2001:db8::fff'.
        Returns a String containing an ipv6 address or ipv6 range that can be provided to the Qualys API. 
    """
    return cidr_to_ip(cidr,4)

def decode_ip_string(ipstring):
    """ Validates ipstring is in a format that can be provided to the Qualys API, if it is not in a format that can be accepted by the Qualys API, it attempts
        to put it in a format that is acceptable (e.g. converting cidr notation to the ip range notation that Qualys expects)
        Returns a string that is valid to hand to the 'ips' key in the Qualys API.
    """
    cml=[]
    ip_list = ipstring.split(',')
    # Should probably check for any repeated or overlapping IP addresses here, but skipping for now.
    for i in ip_list:
        # This is a kludge, but I couldn't come up with a good way to make the error report the string that generated the error, rather than the
        # potentially modified version of the string that caused the error.
        new_i=i 
        if '/' in i:
            new_i = cidr_to_ip(i)
        if (is_valid_ip_address(new_i) or is_valid_ip_range(new_i)):
            cml.append(new_i)
        else:
            raise ValueError, "IP argument cannot be parsed, \'%s\' is not a valid IP Range or IP Address" % i
    return ",".join(cml)

def ip_string_to_cidr(ipstring):
    """ Accepts ipstring - a string list of IPs in the format the Qualys expects or has provided (via API calls) and returns a list of ipaddr.IPNetwork objects."""
    ret_list = []
    ip_list = ipstring.split(',')
    for i in ip_list:
        if is_valid_ip_address(i):
            ret_list.append(ipaddr.IPNetwork(i.strip()))
        elif is_valid_ip_range(i.strip()):
            (start_ip,end_ip) = i.split('-')
            range_list = ipaddr.summarize_address_range(ipaddr.IPAddress(start_ip.strip()), ipaddr.IPAddress(end_ip.strip()))
            for j in range_list:
                ret_list.append(j)
    return ipaddr.collapse_address_list(ret_list)

def ip_list_to_ip_string(iplist):       
    return decode_ip_string(",".join([decode_ip_string(str(i)) for i in iplist]))
def是有效的ip地址(地址,版本=无):
“”“检查地址的有效性
如果“地址”是有效的ipv4或ipv6地址,则返回True。
"""
#验证版本:
如果版本:
如果不是isinstance(版本,int):
raise TypeError,“版本不是“int”类型”
返回错误
如果不是(版本==4或版本==6):
raise VALUERROR,“IP版本设置为无效数字:%s”%version
返回错误
尝试:
ipaddr.IPAddress(address.strip(),版本)
除值错误外:
返回错误
返回真值
def是有效的ipv4地址(地址):
“”“检查地址的有效性
如果“地址”是有效的ipv4地址,则返回True。
"""
返回是有效的ip地址(地址,4)
def是有效的ipv6地址(地址):
“”“检查地址的有效性
如果“地址”是有效的ipv6地址,则返回True。
"""
返回是有效的ip地址(地址,6)
def是有效的ip范围(ip范围,版本=无):
“”“检查iprange的有效性
如果“iprange”是Qulys API将接受格式的ip地址范围(即“startip endip”,其中startipdef is_valid_ip_address(address, version=None):
    """ Check validity of address
        Return True if 'address' is a valid ipv4 or ipv6 address.
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False
    try:
        ipaddr.IPAddress(address.strip(),version)
    except ValueError:
        return False
    return True

def is_valid_ipv4_address(address):
    """ Check validity of address
        Return True if 'address' is a valid ipv4 address.
    """
    return is_valid_ip_address(address,4)

def is_valid_ipv6_address(address):
    """ Check validity of address
        Return True if 'address' is a valid ipv6 address.
    """
    return is_valid_ip_address(address,6)

def is_valid_ip_range(iprange, version=None):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ip addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False

    try:
        (start_ip,end_ip) = iprange.split('-')
        start_ip = start_ip.strip()
        end_ip = end_ip.strip()
        if ipaddr.IPAddress(start_ip) == ipaddr.IPAddress(end_ip):
            logging.debug('%s/%s-%s, Error: %s' % (package,module,version,'Start and End IP Address in an IP Range can not be the same IP Address.'))
            return False
        # A valid range requires:
        # 1) The start_ip must be a valid ip address.
        # 2) The end_ip must be a valid ip address.
        # 3) The start_ip must be less than the end_ip.
        # Although socket operations (as are used in qualysconnect.util) are nice, it's not feasible to determine that the start_ip is less than the 
        # end_ip without considerable effort.  We'll use the ipaddr.summarize_address_range function to test all three at one time.
        ipaddr.summarize_address_range(ipaddr.IPAddress(start_ip,version),ipaddr.IPAddress(end_ip,version))
    except ipaddr.AddressValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        return False
    except ValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        return False
    return True

def is_valid_ipv4_range(iprange):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ipv4 addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    return is_valid_ip_range(iprange,4)

def is_valid_ipv6_range(iprange):
    """ Check validity of iprange
        Return True if 'iprange' is a range of ipv4 addresses in a format that Qulys's API will accept (i.e. "startip-endip" where startip < endip).
    """
    return is_valid_ip_range(iprange,6)

def cidr_to_ip(cidr,version=None):
    """ Convert an ip address or ip range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('10.0.0.0/24') returns the string '10.0.0.0-10.0.0.255'.
        Returns a String containing an ip address or ip range that can be provided to the Qualys API. 
    """
    # Validate version:
    if version:
        if not isinstance(version, int):
            raise TypeError, 'Version is not of type "int"'
            return False
        if not (version == 4 or version == 6):
            raise ValueError, 'IP version is set to an invalid number: %s' % version
            return False
    try:
        cidr_net = ipaddr.IPNetwork(cidr,version)
    except ValueError, e:
        logging.debug('%s/%s-%s, Error: %s' % (package,module,version,e))
        raise ValueError, e
    if cidr_net[0] == cidr_net[-1]:
        return str(cidr_net[0])
    iprange = '%s-%s' % (cidr_net[0],cidr_net[-1])
    return iprange

def cidr_to_ipv4(cidr):
    """ Convert an ipv4 address or ipv4 range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('192.0.2.0/24') returns the string '192.0.2.0-192.0.2.255'.
        Returns a String containing an ip address or ip range that can be provided to the Qualys API. 
    """
    return cidr_to_ip(cidr,4)

def cidr_to_ipv6(cidr):
    """ Convert an ipv6 address or ipv6 range provided in cidr notation (either bitmask or netmask notation) to the ip address or ip range format that is
        accepted by Qualys's API. (e.g. cidr_to_ip('2001:db8::fff/120') returns the string '2001:db8::f00-2001:db8::fff'.
        Returns a String containing an ipv6 address or ipv6 range that can be provided to the Qualys API. 
    """
    return cidr_to_ip(cidr,4)

def decode_ip_string(ipstring):
    """ Validates ipstring is in a format that can be provided to the Qualys API, if it is not in a format that can be accepted by the Qualys API, it attempts
        to put it in a format that is acceptable (e.g. converting cidr notation to the ip range notation that Qualys expects)
        Returns a string that is valid to hand to the 'ips' key in the Qualys API.
    """
    cml=[]
    ip_list = ipstring.split(',')
    # Should probably check for any repeated or overlapping IP addresses here, but skipping for now.
    for i in ip_list:
        # This is a kludge, but I couldn't come up with a good way to make the error report the string that generated the error, rather than the
        # potentially modified version of the string that caused the error.
        new_i=i 
        if '/' in i:
            new_i = cidr_to_ip(i)
        if (is_valid_ip_address(new_i) or is_valid_ip_range(new_i)):
            cml.append(new_i)
        else:
            raise ValueError, "IP argument cannot be parsed, \'%s\' is not a valid IP Range or IP Address" % i
    return ",".join(cml)

def ip_string_to_cidr(ipstring):
    """ Accepts ipstring - a string list of IPs in the format the Qualys expects or has provided (via API calls) and returns a list of ipaddr.IPNetwork objects."""
    ret_list = []
    ip_list = ipstring.split(',')
    for i in ip_list:
        if is_valid_ip_address(i):
            ret_list.append(ipaddr.IPNetwork(i.strip()))
        elif is_valid_ip_range(i.strip()):
            (start_ip,end_ip) = i.split('-')
            range_list = ipaddr.summarize_address_range(ipaddr.IPAddress(start_ip.strip()), ipaddr.IPAddress(end_ip.strip()))
            for j in range_list:
                ret_list.append(j)
    return ipaddr.collapse_address_list(ret_list)

def ip_list_to_ip_string(iplist):       
    return decode_ip_string(",".join([decode_ip_string(str(i)) for i in iplist]))