php – 计算给定网络中可用子网的数量
我在计算网络中可用子网(或主机)的数量时遇到了以下问题.例如,主子网是/ 24(255.255.255.0),其中包含两个/ 25(255.255.255.128)或四个/ 26(255.255.255.192).
因此,如果已经使用了一个节点,那么将只有一个/ 25个或只有3个/ 26个.那么我应该如何计算可用子网的数量.换句话说,如何获得剩余的数量和类型. 解决方法
我使用python来解决这个问题(所有代码都附加了,最后整个脚本),但我确信PHP的解决方案存在类似的库.由于这是旧的并且没有发布解决方案,我猜测任何解决方案(在这种情况下,Python解决方案)都比没有解决方案更好.
该脚本由两个函数组成,一个使用BFS计算“主”子网中的可用子网,另一个使用graphviz创建pdf绘图. 我使用的算法是一个非常简单的BFS.它基本上从顶部子网(“main”,/ 24)开始,并查明是否有任何使用过的(“采用”)子网与它重叠/匹配.如果它们中的任何一个,则算法将它的“子”(/ 25)排队以在同一过程中进行检查.如果算法击中没有“被占用”子节点的子网,则将其标记为“可用”.如果它击中与“已拍摄”完全匹配的子网,则将其标记为“已拍摄”.在任何其他情况下,迭代继续. 可视化的绘制过程是相同的. 这是脚本描述(argparse-generated): usage: script.py [-h] -m M -t TAKEN [TAKEN ...] -o OUTPUT optional arguments: -h,--help show this help message and exit -m M,--m M main subnet to check -t TAKEN [TAKEN ...],--taken TAKEN [TAKEN ...] taken subnets -o OUTPUT,--output OUTPUT graphviz output file name (.pdf) 使用您的参数运行脚本: subnet_script.py -m 255.255.255.0/24 -t 255.255.255.192/26 -o test 给出这些结果: 做一些更有趣的事情,如: script.py -m 255.255.255.0/24 -t 255.255.255.192/26 255.255.255.128/30 -o test 给出这些结果: 我已经使用了ipaddress,queue和graphviz(用于python)模块,以及argparse来使脚本更好用. 第一个功能: def get_available_subnets_set(main,taken): # we assume no subnets are available intially available = [] q = queue.Queue() # add first node for expansion in the BFS process q.put(main) while q.qsize() > 0: subnet = q.get() for taken_subnet in taken: if taken_subnet.compare_networks(subnet) == 0: # found matching subnet in taken,stop expanding print("similar: %s and %s" % (subnet,taken_subnet)) break if taken_subnet.overlaps(subnet): # still has overlaps somewhere in children,keep expanding print("overlaps: %s and %s" % (subnet,taken_subnet)) for sub_subnet in subnet.subnets(): q.put(sub_subnet) break else: # no overlaps with taken - this subnet is entirely available available.append(subnet) return set(available) 第二个函数使用graphviz以类似的方式绘制结果: def make_subnet_graph(main,taken_subnets,available_subnets,filename): g = graphviz.Graph() q = queue.Queue() q.put(main) g.node(str(main)) while q.qsize() > 0: subnet = q.get() for sub_subnet in subnet.subnets(): if sub_subnet in available_subnets: # draw as available (green) g.node(str(sub_subnet),_attributes={"color": "green"}) g.edge(str(sub_subnet),str(subnet)) continue if sub_subnet in taken_subnets: # draw as taken (red) g.node(str(sub_subnet),_attributes={"color": "red"}) g.edge(str(sub_subnet),str(subnet)) continue # has mixed type subnets (taken / available) - go deeper g.node(str(sub_subnet)) g.edge(str(sub_subnet),str(subnet)) q.put(sub_subnet) # write file g.render(filename) 整个事情与argparse一起: #!/usr/bin/env python3.4 import ipaddress import argparse import queue import graphviz def get_available_subnets(main,taken_subnet)) for sub_subnet in subnet.subnets(): q.put(sub_subnet) break else: # no overlaps with taken - this subnet is entirely available available.append(subnet) return available def make_subnet_graph(main,str(subnet)) q.put(sub_subnet) # write file g.render(filename) if "__main__" == __name__: parser = argparse.ArgumentParser() parser.add_argument('-m','--m',help='main subnet to check',required=True) parser.add_argument('-t','--taken',nargs='+',help='taken subnets',required=True) parser.add_argument('-o','--output',help='graphviz output file name (.pdf)',required=True) args = parser.parse_args() taken = [ipaddress.IPv4Network(subnet) for subnet in args.taken] main = ipaddress.IPv4Network(args.m) available = get_available_subnets_set(main,taken) make_subnet_graph(main,taken,available,args.output) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |