工作中需要对地址包含关系进行测试,现有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. Oracle错误——SP2-0734: 未知的命令开头 "imp C##sin..." - 忽略了剩余的行。

    错误 在windows的DOS窗口下使用命令导入Oracle数据. 原因 进入sqlplus里是不能执行imp的(sqlplus不认识imp),imp 是个工具,应该在cmd的dos命令提示符下执行.

  2. RHEL7和RHEL6即时设置、开启和开机、永久开启服务的方法、原理(例子:端口与Nginx冲突的Apache httpd服务的关闭)

    1.RHEL7 说明:启用服务就是在当前 runlevel 的配置文件目录/etc/systemd/system/multi-user.target.wants/里,建立/usr/lib/system ...

  3. (转)开源项目miaosha(下)

    石墨文档:https://shimo.im/docs/2XlwliBQAYsKCHbq/ (二期)20.开源秒杀项目miaosha解读(下) [课程20]jmeter.xmind81.5KB [课程2 ...

  4. LuoguP1041 传染病控制

    题目地址 题目链接 题解 这里讲一个非正解--贪心+随机化. 贪心的想法是什么? 我们dfs一遍处理出每个节点子树内的节点数量,记为\(siz\). 贪心的砍掉\(siz\)最大的那个子树,在树的形态 ...

  5. LOJ6285 数列分块入门9(分块)

    昨天对着代码看了一晚上 然后今天终于在loj上过了 数列分块入门9题撒花★,°:.☆( ̄▽ ̄)/$:.°★ . 然后相当玄学 块的大小调成\(\sqrt{n}\)会TLE,改成150就过了 啧 然后就 ...

  6. Nuget EPPlus的使用

    EPPlus:网站 Supported Functions Excel Merge Operate public class ExcelMergeOperate { private static Lo ...

  7. 2、zabbix工作原理及安装配置

      Zabbix架构:zabbix基本术语.zabbix安装.配置和应用 Zabbix架构中的组件: zabbix-server:C语言    zabbix-server和zabbix-agent通过 ...

  8. 无视编码都统一转成unicode 然后截断 例如 。“发发发发发发” 操作之后显示为 “发发发发...”

    -- local function checkPlayName( str ) -- str = Utils.utf8_to_unicode(str)-- local retStr = "&q ...

  9. 2017"百度之星"程序设计大赛 - 初赛(A) 01,05,06

    小C的倍数问题    Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 32768/32768 K (Java/Others) Problem ...

  10. 使用Coding体验小记

    https://coding.net/ 写了些小程序后放在github上托管,并用gitpages展示. 今天发现用git pages展示的网页网络特别不稳定,时常会出现网页打不开的现象. 之前一直通 ...