Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 计算给定网络中可用子网的数量_Php_Networking_Ip_Binary Tree_Subnet - Fatal编程技术网

Php 计算给定网络中可用子网的数量

Php 计算给定网络中可用子网的数量,php,networking,ip,binary-tree,subnet,Php,Networking,Ip,Binary Tree,Subnet,在计算网络中可用子网(或主机)的数量时,我有以下问题。例如,主子网是/24(255.255.255.0),其中包含两个/25(255.255.255.128)或四个/26(255.255.255.192) 因此,如果一个节点已经被使用,那么只有1/25或3次/26。那么我应该如何计算可用子网的数量。换句话说,如何获得余数的数量和类型。 我想在PHP中执行这个算法。 我使用python解决了这个问题(所有代码都附在后面,最后是整个脚本),但我确信PHP也存在类似的解决方案库。由于这是一个很老的解决

在计算网络中可用子网(或主机)的数量时,我有以下问题。例如,主子网是/24(255.255.255.0),其中包含两个/25(255.255.255.128)或四个/26(255.255.255.192)

因此,如果一个节点已经被使用,那么只有1/25或3次/26。那么我应该如何计算可用子网的数量。换句话说,如何获得余数的数量和类型。 我想在PHP中执行这个算法。

我使用python解决了这个问题(所有代码都附在后面,最后是整个脚本),但我确信PHP也存在类似的解决方案库。由于这是一个很老的解决方案,而且没有发布任何解决方案,我猜任何解决方案(在本例中是Python解决方案)都比没有解决方案好

该脚本由两个函数组成,一个函数使用计算“主”子网内的可用子网,另一个函数使用创建pdf图形

我使用的算法是一个非常简单的BFS。它基本上从顶部子网(“main”和/24)开始,并找出是否有任何使用的(“take”)子网与它重叠/匹配。如果它们中有任何一个这样做了,算法会将它的“子项”(/25)排成队列,以便在同一过程中进行检查。如果算法命中的子网没有“take”子网,则该子网将标记为“available”。如果它访问的子网与“take”完全匹配,则会将其标记为“take”。在任何其他情况下,迭代都将继续

可视化的绘图过程是相同的

以下是脚本说明(argparse生成):

使用您的参数运行脚本:

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
给出了以下结果:

我使用了、和(对于python)模块,并使脚本更易于使用

第一个功能:

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):
    # 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 available

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)


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)
#!/usr/bin/env python3.4

import ipaddress
import argparse
import queue
import graphviz


def get_available_subnets(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 available

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)


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)