工作中需要对地址包含关系进行测试,现有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. Windows 登录用户的类型

    转载:http://blog.csdn.net/chenlycly/article/details/45419259 1.登录的是超级管理员Administrator 默认情况下,超级管理员Admin ...

  2. 配置maven默认jdk版本

    1.在setting.xml中配置.对所有通过该配置文件构建的maven项目有效. <profile> <id>jdk-1.8</id> <activatio ...

  3. 彻底理解mysql服务器的字符集转换问题

    主要参考这三个文章: https://www.xiariboke.com/article/4147.html http://blog.sina.com.cn/s/blog_690c46500100k1 ...

  4. Miller_Rabin整理笔记

    目录 问题 别的 正事 代码 问题 一个数到底是不是素数 别的 首先列一下我们可以求素数的东西 根号暴力求 \(O(nloglogn)\)的埃氏筛 \(O(n)\)的欧拉筛 还有我们要学习的Mille ...

  5. 【原理、应用】Quartz集群原理及配置应用

    一.Quartz任务调度的基本实现原理 Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于Java实现.作为一个优秀的开源调度框架,Quartz具有以下特点: 强大的 ...

  6. IDEA查看一个类的所有继承关系

    通常一个.java文件对应一个java类. 鼠标右击一个类: 即可查看.按住alt键可放大. 另一快捷键:光标在类名上,ctrl+H

  7. Python实现机器学习算法:逻辑回归

    import numpy as np import matplotlib.pyplot as plt from sklearn.datasets.samples_generator import ma ...

  8. Termux 一款安卓终端模拟器

    Termux官网 https://termux.com/ 用处 提供了一个类似于Linux终端的界面,可以使用apt安装程序.目前我在上面跑了我以前写的一些爬虫脚本,运行完全没有问题. 玩法 玩法还是 ...

  9. 订单BOM、销售BOM、标准BOM

    订单BOM.销售BOM.标准BOM   訂單BOM: 是實際生產時用的BOM, 在標準BOM和銷售BOM基礎上增減物料的BOM銷售BOM: 是為特定客戶設定的BOM, 在主檔數據層次上的BOM, 在生 ...

  10. Mac python 2.X 升级到 3.X

    Mac OS X10.9默认带了Python2.7,不过现在Python3.3.3出来了,如果想使用最新版本,赶紧升级下吧.基本步骤如下. 第1步:下载Python3.3 下载地址如下: Python ...