【问题标题】:Select every first and last IP Address of subnet ranges选择子网范围的每个第一个和最后一个 IP 地址
【发布时间】:2022-01-03 00:09:17
【问题描述】:

我有一个子网172.16.0.0/22,其中有四个范围172.16.0.0 → 172.16.0.255 172.16.1.0 → 172.16.1.255172.16.2.0 → 172.16.2.255172.16.3.0 → 172.16.3.255。我正在使用netaddr 来查找这些范围。

import netaddr

network = netaddr.IPNetwork(addr="172.16.0.0/22")

print(list(network))
# output
[
IPAddress("172.16.0.0"), 
IPAddress("172.16.0.1"),
...,
IPAddress("172.16.0.254"),
IPAddress("172.16.0.255"),
...,
IPAddress("172.16.1.0"),
IPAddress("172.16.1.1"),
...,
IPAddress("172.16.1.254"),
IPAddress("172.16.1.255"),
...,
IPAddress("172.16.2.0"),
IPAddress("172.16.2.1"),
...,
IPAddress("172.16.2.254"),
IPAddress("172.16.2.255"),
...,
IPAddress("172.16.3.0"),
IPAddress("172.16.3.1"),
...,
IPAddress("172.16.3.254"),
IPAddress("172.16.3.255"),
]

如何选择每个范围的每个 .1.254?即,我怎样才能得到这样的输出

[
    (172.16.0.1, 172.16.0.254), 
    (172.16.1.1, 172.16.1.254),
    (172.16.2.1, 172.16.2.254),
    (172.16.3.1, 172.16.3.254)
]

【问题讨论】:

    标签: python python-3.x subnet


    【解决方案1】:

    试试这个:

    result = [(str(network[256 * r + 1]), str(network[256 * r + 254]))
              for r in range(len(network) // 256)]
    

    基本上对于每个范围(有len(network) // 256 范围),您都取元素 n。 1 (network[256 * r + 1]) 和 n。 254 (network[256 * r + 254])。这些元素是 <class 'netaddr.ip.IPAddress'> 类的实例:为了将它们转换为字符串,您只需使用 str 内置函数即可。

    【讨论】:

    • 像魅力一样工作!但是你能解释一下吗?非常感谢
    • @Tes3awy 完成 ;)
    【解决方案2】:

    我没有尝试使用 netaddr 对象,但代码也应该按原样运行,因为我将地址转换为字符串。但这并不完全是您想要的。每个范围的地址都保存在列表中。

    network = [
    "172.16.0.0","172.16.0.1","172.16.0.254","172.16.0.255","172.16.1.0",
    "172.16.1.1","172.16.1.254","172.16.1.255","172.16.2.0","172.16.2.1",
    "172.16.2.254","172.16.2.255","172.16.3.0",
    "172.16.3.1","172.16.3.254","172.16.3.255",
    ]
    
    def get_adress(network):
        output,tmp = [],[]
        for ad in network:
            ad_str = str(ad)
    
            if ad_str.endswith('.1') or ad_str.endswith('.254'):
                tmp.append(ad_str)
                if len(tmp)==2:
                    output.append(tmp)
                    tmp= []
        return(output)
    
    output= get_adress(network)
    print(output)
    
    >>[['172.16.0.1', '172.16.0.254'],
     ['172.16.1.1', '172.16.1.254'],
     ['172.16.2.1', '172.16.2.254'],
     ['172.16.3.1', '172.16.3.254']]
    

    编辑

    这现在将地址作为列表中的元组。

    def get_adress(network):
        one,two = [],[]
    
        for ad in network:
            ad_str = str(ad)
            if ad_str.endswith('.1'): 
                one.append(ad_str)
            elif ad_str.endswith('.254'):
                two.append(ad_str)
    
        return(list(zip(one, two)))
    
    output= get_adress(network)
    output
    
    >>[('172.16.0.1', '172.16.0.254'),
     ('172.16.1.1', '172.16.1.254'),
     ('172.16.2.1', '172.16.2.254'),
     ('172.16.3.1', '172.16.3.254')]
    

    【讨论】:

    • 非常感谢您的帮助。我实际上想到了与您完全相同的方式。我的是first_ips = [str(ip) for ip in network if str(ip).endswith(".1")] last_ips = [str(ip) for ip in network if str(ip).endswith(".254")] ips = list(zip(start_ips, last_ips))。但我接受的答案更有意义,更优雅。再次感谢您!
    【解决方案3】:

    检查每个 IP 地址中的最后一个八进制以查看它们是否是所需的数字。我更喜欢这个解决方案,因为它只使用 netaddr 对象结构。

    [n for n in network if n.words[-1] in [1, 254]]
    

    【讨论】:

    • 记得将结果转换为字符串。此外,用户不希望有一个普通列表,而是一个元组列表
    猜你喜欢
    • 2016-03-19
    • 2016-01-01
    • 2013-09-15
    • 1970-01-01
    • 2014-05-06
    • 2010-12-08
    • 2020-01-10
    • 2014-07-31
    • 2013-12-21
    相关资源
    最近更新 更多