简体   繁体   English

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

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

from ipaddress class, I know the address_exclude method.ipaddress class,我知道address_exclude方法。 below is an example from the documentation:以下是文档中的示例:

>>> 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')]

but what about if I want to remove two or more subnets from a network?但是如果我想从网络中删除两个或更多子网怎么办? for example, how can I delete from the 192.168.10.0/26 his subnets 192.168.10.24/29 and 192.168.10.48/28?例如,如何从 192.168.10.0/26 中删除他的子网 192.168.10.24/29 和 192.168.10.48/28? the result should be 192.168.10.0/28, 192.168.10.16/29 and 192.168.10.32/28.结果应该是 192.168.10.0/28、192.168.10.16/29 和 192.168.10.32/28。

I'm trying to find a way to write the algoritm that I use in my mind using the address_exclude method but I can't.我正在尝试找到一种方法来使用address_exclude方法编写我在脑海中使用的算法,但我做不到。 is there a simple way to implement what I just explained?有没有一种简单的方法来实现我刚才解释的内容?

When you exclude one network from another, the result can be multiple networks (original one got split) - so, for the rest of the networks to exclude, you need to first find which part they would fit into before excluding them as well.当您从另一个网络中排除一个网络时,结果可能是多个网络(原始网络被拆分) - 因此,对于要排除的网络的 rest,您需要先找到它们适合的部分,然后再排除它们。

Here's one possible solution:这是一种可能的解决方案:

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: Output:

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

Expanding on my brain wave posted on @rdas's response, posting my solution.扩展我在@rdas 的回复上发布的脑电波,发布我的解决方案。

It seems better to split the initial network into the smallest chunks you are asking, and do this for all ranges to be removed.将初始网络拆分为您要求的最小块似乎更好,并为要删除的所有范围执行此操作。 Then exclude them from the list and return result.然后将它们从列表中排除并返回结果。

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}")

With the result:结果:

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']

Which seems to be valid.这似乎是有效的。

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

相关问题 如何从 Python 的单个输入中删除列表的两个或多个对象? - How can I remove two or more objects of a list from a single input in Python? 如何从路由表 txt 中获取网络/子网和下一跳 - How to get network/subnet and nexthop from a routing table txt 如何从文件中删除最后两个字符? - How can I remove the last two characters from my file? 如何在没有循环的情况下从列表中删除两个元素? - How can I remove two elements from a list without a loop? 如何从 Python 中的单个输入将两个或多个元素添加到列表中? - How can I add two or more elements to a list from a single input in Python? 如果元组在 Python 中包含两个相邻的“1”,如何从列表中删除元组? - How can I remove a tuple from a list if the tuple contains two "1" next to each other in Python? 如何找到关键列上两个数据帧之间的差异并从两个数据帧中删除唯一记录 - How can i find the difference between two dataframes on key column and remove the unique records from both dataframes 如何使用此代码在Python 3中解析另外两个文件? - How can I use this code to parse two more files in Python 3? 如何合并两个(或更多)TensorFlow 数据集? - How can I merge two (or more) TensorFlow datasets? SNPE - 如何预测具有两个(或更多)输入的 model? - SNPE - How can I predict on a model with two (or more) inputs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM