• 自己动手编写IPv4地址包含关系测试的小脚本


    工作中需要对地址包含关系进行测试,现有ipaddress标准库和IPy无法满足,于是自己动手编写小脚本,主要实现== , in, <等专用功能,其他功能可以后续用到再补充,例如迭代打印网段内所有地址,输出前缀长度等等。


    一,含有的类:
    Host类:主机地址,eg, Host('192.168.1.1')
    Network类:网络地址,eg,Network('192.168.1.0 255.255.255.0')
    AddressGroup类:主机地址和网络地址组成的列表,eg,AddressGroup(['192.168.1.0 255.255.255.0', '10.1.1.1'])


    二,实现的功能:

    Host—>Network—>AddressGroup,低级别向高级别支持in测试
    Network/AddressGroup同类之间支持<=测试

    1)Host in Network,Host in AddressGroup测试
    Host('192.168.1.1') in Network('192.168.1.0 255.255.255.0') # True
    Host('192.12.1.5') in Network('192.0.1.0 255.0.255.0') # True,Network可以是通配符
    Host('192.12.1.5') in AddressGroup(['192.168.1.0 255.255.255.0', '10.1.1.1']) # True

    2)Network in AddressGroup测试
    Network(192.168.1.0 255.255.255.0) in AddressGroup(['192.168.0.0 255.255.0.0', '10.1.1.1'])

    3)Network <= Network测试
    Network(192.168.1.0 255.255.255.0) <= Network('192.168.0.0 255.255.0.0') # True
    Network(192.0.1.0 255.0.255.0) <= Network('192.168.0.0 255.255.0.0') # False,Network可以是通配符

    4)AddressGroup <= AddressGroup测试
    AddressGroup(['192.168.1.0 255.255.255.0', '10.1.1.1']) <= AddressGroup(['192.168.0.0 255.255.255.0', '10.1.1.1']) # True

    5)前缀修正
    n1 = Network('192.168.1.0 255.0.255.0')
    n1.network # 192.0.1.0


    三,由于数据源都是标准的地址格式,因此很多细节和出错控制未考虑:
    Address('300.1000.2.1') # 未做地址或者网段的出错控制,仅控制了split('.')是否等于4以及元素是否是整数
    AddressGroup含C类host明细时,与所属AddressGroup网段进行eq比较时会不等

    class AddressValueError(ValueError):
        """A Value Error related to the netmask."""
    
    
    def ip_address(address):
        try:
            return Host(address)
        except AddressValueError:
            pass
    
        try:
            return Network(address)
        except AddressValueError:
            pass
    
        raise AddressValueError('Not a valid host or network address: {!r}'.format(address))
    
    
    def _host_int_from_string(address):
        octets = address.split('.')
        if len(octets) != 4:
            raise AddressValueError("Expected 4 octets in {!r}".format(address))
        try:
            return [int(i) for i in octets]
        except ValueError as exc:
            raise AddressValueError("%s in %r" % (exc, address)) from None
    
    
    def _network_int_from_string(address):
        parts = address.split()
        if len(parts) != 2:
            raise AddressValueError("Expected network plus netmask in {!r}".format(address))
        return _host_int_from_string(parts[0]), _host_int_from_string(parts[1])
    
    
    class Host(object):
        """eg, address: 192.168.1.1"""
        __slots__ = ('_address', '_host')
    
        def __init__(self, address):
            self._address= address
            self._host = _host_int_from_string(address)
    
        def __repr__(self):
            return '<Host:{!r}>'.format(self._address)
    
        def __eq__(self, other):
            try:
                return self._address == other._address
            except AttributeError:
                return NotImplemented
    
    
    class Network(object):
        """eg, address: 192.168.1.0 255.255.255.0"""
        __slots__ = ('_address', '_network', '_netmask')
    
        def __init__(self, address):
            self._address = address
            self._network, self._netmask = _network_int_from_string(address)
            self._network = [i[0] & i[1] for i in zip(self._network, self._netmask)]
    
        def __contains__(self, other):
            if isinstance(other, Host):
                network_other = [i[0] & i[1] for i in zip(other._host, self._netmask)]
                if self._network == network_other:
                    return True
            return False
    
        def __eq__(self, other):
            try:
                return self._network == other._network and self._netmask == other._netmask
            except AttributeError:
                return NotImplemented
    
        def __le__(self, other):
            if isinstance(other, Network):
                parts = [i[0] & i[1] for i in zip(self._network, other._netmask)]
                if parts == other._network and all([i[0] >= i[1] for i in zip(self._netmask, other._netmask)]):
                    return True
            return False
    
        def __repr__(self):
            return '<Network:{!r}>'.format(self._address)
    
        @property
        def network(self):
            return '.'.join([str(i) for i in self._network])
    
    
    class AddressGroup(object):
        """ eg,address_group: ['192.168.1.1', '192.168.1.2', '10.1.1.0 255.255.255.0']
        无法继承abc.Set,因为abc.Set中两个Set长度相等直接返回Fasle,本类不一定,因此需要重构__lt__特殊方法 """
        def __init__(self, components):
            self._components = list(components)
            self._compObjs = [ip_address(i) for i in components]
    
        def __len__(self):
            return len(self._components)
    
        def __iter__(self):
            for c in self._compObjs:
                yield c
    
        def __contains__(self, other):
            if isinstance(other, Host):
                for obj in self:
                    cond1 = isinstance(obj, Host) and other == obj
                    cond2 = isinstance(obj, Network) and other in obj
                    if cond1 or cond2:
                        return True
            if isinstance(other, Network):
                for obj in self:
                    if isinstance(obj, Network) and other <= obj:
                        return True
            return False
    
        def __eq__(self, other):
            try:
                return sorted(self._components) == sorted(other._components)
            except AttributeError:
                return NotImplemented
    
        def __lt__(self, other):
            return all([i in other for i in self._compObjs])
    
        def __repr__(self):
            return '<AddressGroup:{!r}>'.format(' | '.join(self._components))
  • 相关阅读:
    LeetCode #4 中等题(二分,中位数)
    LeetCode #3 简单题(map标记)
    leetCode #2 简单题(链表)
    LeetCode #1 简单题(map存一下基本就O(nlogn)复杂度)
    CMake使用入门笔记( 1 ) BuildSystem的三个指令 --- 更新中
    (模拟)hihocoder
    (暴力)UVA
    (IDA*)HDU
    总结
    (模拟+贪心)codeforces
  • 原文地址:https://www.cnblogs.com/guxh/p/10162951.html
Copyright © 2020-2023  润新知