工作中需要对地址包含关系进行测试,现有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))

自己动手编写IPv4地址包含关系测试的小脚本的更多相关文章

  1. IPv4地址范围和一些小知识

    IP地址范围:         保留地址(私有IP地址): 10.0.0.0——10.255.255.255 172.16.0.0——172.31.255.255 192.168.0.0——192.1 ...

  2. OWIN系列之自己动手编写中间件

    一.前言 1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器. 2.OWIN.dll介绍 使用反编 ...

  3. IPv4地址学习总结

    一. IPv4地址格式 网络互连的一个重要前提条件是要有一个有效的地址结构,并且所有的互连网络用户都应遵守这个地址结构.因为只有这样所有的互连网络用户才能在统一的规定下相互之间通讯.这个地址结构可以有 ...

  4. IPv4地址分类及子网划分

    IPv4地址分为A,B,C,D,E类: A类:1.0.0.0~126.255.255.255,默认子网掩码/8,即255.0.0.0 (其中127.0.0.0~127.255.255.255为环回地址 ...

  5. IPv4地址分类及特征

    IPv4地址分类及特征 IP地址后斜杠和数字代表的意思 其中有这样一个IP地址的格式:IP/数字,例如:111.222.111.222/24 这种格式平时在内网中用的不多,所以一下子看不懂,最后查了资 ...

  6. 如何通过C语言获取主机WLAN下的IPv4地址,MAC地址

    #include "stdio.h" #include "windows.h" void GetHostWLAN_IPv4_AND_MAC(char IPv4[ ...

  7. Linux dts 设备树详解(二) 动手编写设备树dts

    Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 前言 硬件结构 设备树dts文件 前言 在简单了解概念之后,我们可以开始尝试写一个 ...

  8. IPv4地址段、地址掩码、可用地址等常用方法

    package com.xxx.iptools; import java.util.ArrayList; import java.util.HashMap; import java.util.List ...

  9. (超详细)动手编写 — 栈、队列 ( Java实现 )

    目录 前言 栈 概念 栈的设计 编码实现 小结 队列 概念 队列的设计 编码实现 双端队列 概念 设计 编码 循环队列 循环队列 循环双端队列 声明 前言 栈 概念 什么是栈? **栈 **:是一种特 ...

随机推荐

  1. PT,PX,DPI

    [iOS]查找数组NSArray中是否包含指定的元素 http://blog.csdn.net/zyq527758142/article/details/51278172 Dpi(每平方英寸像素数目) ...

  2. Bootstrap3基础 glyphicon 设置图标的颜色与大小

      内容 参数   OS   Windows 10 x64   browser   Firefox 65.0.2   framework     Bootstrap 3.3.7   editor    ...

  3. linux内核中的cfq输入输出调度算法

    1. 全称是什么? 完全公平调度算法(completely fair queuing) 2. 原理是怎样的? 先按照输入输出请求的地址进行排序,然后按排好的次序执行请求 3. 适用场景 适用于旋转式磁 ...

  4. yum命令showduplicates安装指定版本包

    默认情况下,我们用yum list 或者 yum install 的时候,yum会默认选择最新的版本. 如果我们需要安装指定版本的某个软件包,以使之能够和我们现有环境的软件包版本匹配,那么就需要用到s ...

  5. SPOJ 687 REPEATS - Repeats

    题意 给定字符串,求重复次数最多的连续重复子串 思路 后缀数组的神题 让我对着题解想了快1天 首先考虑一个暴力,枚举循环串的长度l,然后再枚举每个点i,用i和i+l匹配,如果匹配长度是L,这个循环串就 ...

  6. LOJ6283 数列分块入门7(分块)

    pushdown的addtag[x]打成addtag[i],结果WA了一次 #include <cstdio> #include <algorithm> #include &l ...

  7. facebook api之Access and Authentication

    Access and Authentication There are three access levels to the Marketing APIs. You can upgrade acces ...

  8. NLog——ElasticSearch——Kibana

    Nlog.elasticsearch.Kibana以及logstash在项目中的应用(一) Nlog.elasticsearch.Kibana以及logstash在项目中的应用(二) ASP.NET ...

  9. Android四种布局方式

    线性布局 <LinearLayout android:layout_width="match_parent" android:layout_height="wrap ...

  10. Python pycharm 常用快捷键

    快捷键 1.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性) Ctrl + Alt + Space 快速导入任意类 Ctrl + Shift + Enter 语句完成 ...