【问题标题】:Calculating all IPs in subnet using Python 2.7 built in modules only仅使用 Python 2.7 内置模块计算子网中的所有 IP
【发布时间】:2017-05-14 01:59:39
【问题描述】:

我想知道如何创建一个采用这样的 cidr 表示法的脚本:

204.15.20.0/22

并计算该范围内所有可能的 IP 地址。

204.15.20.0
...
...
204.15.23.255

现在我终于知道这背后的数学原理了,我想知道如何在 python 中制作这样的模块。

我知道 netaddr.IPNetwork() 等现成可用的模块,但我想知道如何做到这一点,只使用 Python 2.7 中的内置模块

谢谢:)

【问题讨论】:

  • 您可以将该地址更改为整数并从那里使用range
  • 我不认为它是这样工作的,因为单个八位字节的最大值只能是 255 (b11111111)
  • @UrielEli 不是重复的,我知道它背后的数学,如我的 OP 中所说。我想知道如何使用内置模块在 Python 中做到这一点。

标签: python python-2.7 ip subnet cidr


【解决方案1】:

您可以结合使用socketstruct 模块在IPv4 地址和整数之间进行转换。之后,它的问题是屏蔽整数地址并从 cidr 值中找出子网中的值范围。

import re
import socket
import struct

def inet_atoi(ipv4_str):
    """Convert dotted ipv4 string to int"""
    # note: use socket for packed binary then struct to unpack
    return struct.unpack("!I", socket.inet_aton(ipv4_str))[0]

def inet_itoa(ipv4_int):
    """Convert int to dotted ipv4 string"""
    # note: use struct to pack then socket to string
    return socket.inet_ntoa(struct.pack("!I", ipv4_int))

def ipv4_range(ipaddr):
    """Return a list of IPv4 address contianed in a cidr address range"""
    # split out for example 192.168.1.1:22/24
    ipv4_str, port_str, cidr_str = re.match(
        r'([\d\.]+)(:\d+)?(/\d+)?', ipaddr).groups()

    # convert as needed
    ipv4_int = inet_atoi(ipv4_str)
    port_str = port_str or ''
    cidr_str = cidr_str or ''
    cidr_int = int(cidr_str[1:]) if cidr_str else 0

    # mask ipv4
    ipv4_base = ipv4_int & (0xffffffff << (32 - cidr_int))

    # generate list
    addrs = [inet_itoa(ipv4_base + val)
        for val in range(1 << (32 - cidr_int) + 2)]
    return addrs

print(ipv4_range('204.15.20.0/22'))

【讨论】:

    猜你喜欢
    • 2017-12-05
    • 1970-01-01
    • 2012-12-02
    • 2019-07-28
    • 2017-06-10
    • 2017-06-19
    • 1970-01-01
    • 2019-08-21
    相关资源
    最近更新 更多