繁体   English   中英

如何从网络中删除两个或多个子网?

[英]How can I remove two or more subnet from a network?

ipaddress class,我知道address_exclude方法。 以下是文档中的示例:

>>> n1 = ip_network('192.0.2.0/28')
>>> n2 = ip_network('192.0.2.1/32')
>>> list(n1.address_exclude(n2))  
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
 IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]

但是如果我想从网络中删除两个或更多子网怎么办? 例如,如何从 192.168.10.0/26 中删除他的子网 192.168.10.24/29 和 192.168.10.48/28? 结果应该是 192.168.10.0/28、192.168.10.16/29 和 192.168.10.32/28。

我正在尝试找到一种方法来使用address_exclude方法编写我在脑海中使用的算法,但我做不到。 有没有一种简单的方法来实现我刚才解释的内容?

当您从另一个网络中排除一个网络时,结果可能是多个网络(原始网络被拆分) - 因此,对于要排除的网络的 rest,您需要先找到它们适合的部分,然后再排除它们。

这是一种可能的解决方案:

from ipaddress import ip_network, collapse_addresses

complete = ip_network('192.168.10.0/26')

# I chose the larger subnet for exclusion first, can be automated with network comparison
subnets = list(complete.address_exclude(ip_network('192.168.10.48/28')))
# other network to exclude
other_exclude = ip_network('192.168.10.24/29')

result = []
# Find which subnet the other exclusion will happen in 
for sub in subnets:
    # If found, exclude & add the result
    if other_exclude.subnet_of(sub):
        result.extend(list(sub.address_exclude(other_exclude)))
    else:
    # Other subnets can be added directly
        result.append(sub)

# Collapse in case of overlaps
print(list(collapse_addresses(result)))

Output:

[IPv4Network('192.168.10.0/28'), IPv4Network('192.168.10.16/29'), IPv4Network('192.168.10.32/28')]

扩展我在@rdas 的回复上发布的脑电波,发布我的解决方案。

将初始网络拆分为您要求的最小块似乎更好,并为要删除的所有范围执行此操作。 然后将它们从列表中排除并返回结果。

from ipaddress import ip_network, collapse_addresses

def remove_ranges(mynetwork,l_of_ranges):
    # find smallest chunk
    l_chunk = sorted(list(set([x.split('/')[1] for x in l_of_ranges])))
    l_mynetwork = list(ip_network(mynetwork).subnets(new_prefix=int(l_chunk[-1])))

    l_chunked_ranges = [ ]
    for nw in l_of_ranges:
        l_chunked_ranges.extend(list(ip_network(nw).subnets(new_prefix=int(l_chunk[-1]))))

    l_removed_networks = [ ]
    for mynw in l_mynetwork:
        if not mynw in l_chunked_ranges:
            l_removed_networks.append(mynw)

    result = list(collapse_addresses(l_removed_networks))

    return [str(r) for r in result]


if __name__ == '__main__':
    mynetwork = "10.110.0.0/16"
    l_of_ranges = ["10.110.0.0/18","10.110.72.0/21","10.110.80.0/21","10.110.96.0/21"]

    print(f"My network: {mynetwork}, Existing: {l_of_ranges} ")
    a = remove_ranges(mynetwork,l_of_ranges)
    print(f"Remaining: {a}")

结果:

My network: 10.110.0.0/16, Existing: ['10.110.0.0/18', '10.110.72.0/21', '10.110.80.0/21', '10.110.96.0/21'] 
Remaining: ['10.110.64.0/21', '10.110.88.0/21', '10.110.104.0/21', '10.110.112.0/20', '10.110.128.0/17']

这似乎是有效的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM