如何获取 python 中网络的所有可能子网 ID?
How to get all possible subnet ID of a network in python?
尝试创建一个函数,该函数 returns 给定网络 ID、子网掩码、默认掩码、感兴趣的八位字节和幻数的所有可能子网 ID 的列表。函数里面感觉classful subnet mask也必须要用但是好像能写个有用的程序
def getAllSubnet(networkID, SubnetMask, classfulSubnetMask, octetInterest, magicNumber):
classfulSubnetMask = classfulSubnetMask.split('.')
SubnetMask = SubnetMask.split('.')
allSubnet = []
for _ in range(0, int(SubnetMask[octetInterest-1]), magicNumber):
networkID = networkID.split('.')
networkID[octetInterest-1] = str(int(networkID[octetInterest-1])+magicNumber)
networkID = '.'.join(networkID)
allSubnet.append(networkID)
return allSubnet
networkID = '16.0.0.0'
subnetRequested = '500'
classfulSubnetMask = '255.0.0.0'
subnetMask = '255.255.128.0'
octetInterest = 3
magicNumber = 128
print(getAllSubnet(networkID, subnetMask, classfulSubnetMask, octetInterest, magicNumber))
网络和主机 ID 的解释
通常有两种类型的IPv4寻址方法,classful和classless。由于您的示例包含有关 classful 子网划分的信息,因此我假设您想计算给定 IPv4 class 和子网掩码的可能子网数。如果您正在寻找其他内容,我可以根据需要编辑答案。
处理 IPv4 地址(A、B、C、D、E)时有 5 个 classes。每个 class 在 IP 地址的第一个八位字节(前 8 位)中确定。
您可以在此处阅读有关确定 IPv4 class 的更多信息:https://www.tutorialspoint.com/ipv4/ipv4_address_classes.htm
需要注意的是,class完整的 IP 地址在现实世界中不再使用。
话虽如此,根据您提供的示例,您可以按照以下方式分解此信息。
首先是“有类子网掩码”,它将用于确定您的 IP 地址中有多少位构成 class。用于 class 的任何位都不能用于您的子网或主机 ID(主机 ID 是您网络上的实际单个节点)。
然后你有你的“子网掩码”,它告诉你哪些位组成你的子网 ID 和你的主机 ID。
最后,您获得了“网络 ID”,它向我们展示了将用于所有子网和主机 ID 的实际前缀。所以如下:
有类子网掩码: 255.0.0.0(二进制表示:11111111.00000000.00000000.00000000)
子网掩码: 255.255.128.0(二进制表示:11111111.11111111.10000000.00000000)
网络 ID:16.0.0.0(二进制表示:00010000.00000000.00000000.00000000)
我们知道 classful 子网掩码设置的位是为您的网络 ID 保留的(即不能被子网使用),我们也知道子网掩码未设置的位是保留的对于主机(子网掩码末尾的最后 15 个 0)。
这意味着我们要计算出子网掩码中的这些 1 中有多少是 唯一的 子网掩码并且不包含在您的 classful 掩码中。在我们的示例中,十进制表示为“0.255.128.0”,二进制表示为“00000000.11111111.10000000.00000000”。
因此我们有 9 位子网地址 space,如果我们取 2^9,我们将得到 512 个可能的子网 ID。然后我们知道,基于我们的网络 ID 16.0.0.0,我们的子网 ID 范围从 16.0.0.0 到 16.255.128.0。我们还知道每个子网可以有 32,768 台主机。例如,如果您的网络 ID 和子网 ID 等于 16.0.0.0,我们可以拥有 16.0.0.1 到 16.0.127.255 范围内的主机。
使用 Python“ipaddress”库实施解决方案
使用 python 中的“ipaddress”库,我们可以很容易地解决查找所有可能子网的问题。我将 post 示例代码,然后在下面进行解释。
import ipaddress
# Here I've left your variables exactly as they were in case this format is a requirement.
networkID = '16.0.0.0'
subnetRequested = '500'
classfulSubnetMask = '255.0.0.0'
subnetMask = '255.255.128.0'
octetInterest = 3
magicNumber = 128
# Calculate how many 1's are set in the binary forms of both net masks
subnetMaskBits = bin(int(ipaddress.IPv4Address(subnetMask))).count("1")
classfulMaskBits = bin(int(ipaddress.IPv4Address(classfulSubnetMask))).count("1")
# Create an ip_network object using our network address and in CIDR notation
fullAddress = ipaddress.ip_network(networkID + "/" + str(classfulMaskBits))
# Print out all possible subnets against our fulladdress with subnet mask
output = list(fullAddress.subnets(prefixlen_diff=(subnetMaskBits-classfulMaskBits)))
# Print the addresses (note there are going to be a LOT of them)
print (output)
代码相对简单,但有几处可能需要解释。首先,我们计算两种网络掩码二进制形式中 1 的数量。然后我们创建一个 ip_network 对象(python ipaddress 库的一部分)并使用 CIDR 表示法对其进行初始化。
CIDR 代表无类域间路由,在现实世界中用于代替 classful(我们在您的示例中使用的)。我们在这里使用它只是因为它可以让我们轻松计算出我们的子网 ID。
CIDR 表示法类似于 (16.0.0.0/8),其中“/8”表示掩码中 1 的数量。因此,对于完整地址,我们从 classful 子网掩码中传递 1 的数量,即 8。
这个 python 库有一个名为“子网”的函数,它可以完全满足您的问题。您在这里唯一需要知道的是“prefixlen_diff”参数。这个参数基本上是说为我们的子网 ID 保留了多少位。这将等于我们的 classful 掩码中 1 的数量从我们的子网掩码中减去(如上所述)。
更清楚地总结一下:
网络IP地址:16.0.0.0
分类掩码: 255.0.0.0 (11111111.00000000.00000000.00000000)
Classful Mask 1's: 8
网络 IP CIDR 表示法: 16.0.0.0/8
然后对于子网:
子网掩码: 255.255.128.0 (11111111.11111111.10000000.00000000)
子网掩码中的 1: 17
1 的唯一子网掩码: 9 (00000000.11111111.10000000.00000000)
都适用于这行代码:
output = list(fullAddress.subnets(prefixlen_diff=(subnetMaskBits-classfulMaskBits)))
其中 fullAddress 是“16.0.0.0/8”,prefixlen_diff 是 9 (17 - 8)。
我们调用带有列表的子网方法来迭代出所有可能的子网 ID。我们实际上根本不需要 octetInterest 或 magicNumber 变量。
希望我回答了你想问的问题,但如果你正在寻找不同类型的输出,我可以根据需要编辑它。
尝试创建一个函数,该函数 returns 给定网络 ID、子网掩码、默认掩码、感兴趣的八位字节和幻数的所有可能子网 ID 的列表。函数里面感觉classful subnet mask也必须要用但是好像能写个有用的程序
def getAllSubnet(networkID, SubnetMask, classfulSubnetMask, octetInterest, magicNumber):
classfulSubnetMask = classfulSubnetMask.split('.')
SubnetMask = SubnetMask.split('.')
allSubnet = []
for _ in range(0, int(SubnetMask[octetInterest-1]), magicNumber):
networkID = networkID.split('.')
networkID[octetInterest-1] = str(int(networkID[octetInterest-1])+magicNumber)
networkID = '.'.join(networkID)
allSubnet.append(networkID)
return allSubnet
networkID = '16.0.0.0'
subnetRequested = '500'
classfulSubnetMask = '255.0.0.0'
subnetMask = '255.255.128.0'
octetInterest = 3
magicNumber = 128
print(getAllSubnet(networkID, subnetMask, classfulSubnetMask, octetInterest, magicNumber))
网络和主机 ID 的解释
通常有两种类型的IPv4寻址方法,classful和classless。由于您的示例包含有关 classful 子网划分的信息,因此我假设您想计算给定 IPv4 class 和子网掩码的可能子网数。如果您正在寻找其他内容,我可以根据需要编辑答案。
处理 IPv4 地址(A、B、C、D、E)时有 5 个 classes。每个 class 在 IP 地址的第一个八位字节(前 8 位)中确定。
您可以在此处阅读有关确定 IPv4 class 的更多信息:https://www.tutorialspoint.com/ipv4/ipv4_address_classes.htm
需要注意的是,class完整的 IP 地址在现实世界中不再使用。
话虽如此,根据您提供的示例,您可以按照以下方式分解此信息。
首先是“有类子网掩码”,它将用于确定您的 IP 地址中有多少位构成 class。用于 class 的任何位都不能用于您的子网或主机 ID(主机 ID 是您网络上的实际单个节点)。
然后你有你的“子网掩码”,它告诉你哪些位组成你的子网 ID 和你的主机 ID。
最后,您获得了“网络 ID”,它向我们展示了将用于所有子网和主机 ID 的实际前缀。所以如下:
有类子网掩码: 255.0.0.0(二进制表示:11111111.00000000.00000000.00000000)
子网掩码: 255.255.128.0(二进制表示:11111111.11111111.10000000.00000000)
网络 ID:16.0.0.0(二进制表示:00010000.00000000.00000000.00000000)
我们知道 classful 子网掩码设置的位是为您的网络 ID 保留的(即不能被子网使用),我们也知道子网掩码未设置的位是保留的对于主机(子网掩码末尾的最后 15 个 0)。
这意味着我们要计算出子网掩码中的这些 1 中有多少是 唯一的 子网掩码并且不包含在您的 classful 掩码中。在我们的示例中,十进制表示为“0.255.128.0”,二进制表示为“00000000.11111111.10000000.00000000”。
因此我们有 9 位子网地址 space,如果我们取 2^9,我们将得到 512 个可能的子网 ID。然后我们知道,基于我们的网络 ID 16.0.0.0,我们的子网 ID 范围从 16.0.0.0 到 16.255.128.0。我们还知道每个子网可以有 32,768 台主机。例如,如果您的网络 ID 和子网 ID 等于 16.0.0.0,我们可以拥有 16.0.0.1 到 16.0.127.255 范围内的主机。
使用 Python“ipaddress”库实施解决方案
使用 python 中的“ipaddress”库,我们可以很容易地解决查找所有可能子网的问题。我将 post 示例代码,然后在下面进行解释。
import ipaddress
# Here I've left your variables exactly as they were in case this format is a requirement.
networkID = '16.0.0.0'
subnetRequested = '500'
classfulSubnetMask = '255.0.0.0'
subnetMask = '255.255.128.0'
octetInterest = 3
magicNumber = 128
# Calculate how many 1's are set in the binary forms of both net masks
subnetMaskBits = bin(int(ipaddress.IPv4Address(subnetMask))).count("1")
classfulMaskBits = bin(int(ipaddress.IPv4Address(classfulSubnetMask))).count("1")
# Create an ip_network object using our network address and in CIDR notation
fullAddress = ipaddress.ip_network(networkID + "/" + str(classfulMaskBits))
# Print out all possible subnets against our fulladdress with subnet mask
output = list(fullAddress.subnets(prefixlen_diff=(subnetMaskBits-classfulMaskBits)))
# Print the addresses (note there are going to be a LOT of them)
print (output)
代码相对简单,但有几处可能需要解释。首先,我们计算两种网络掩码二进制形式中 1 的数量。然后我们创建一个 ip_network 对象(python ipaddress 库的一部分)并使用 CIDR 表示法对其进行初始化。
CIDR 代表无类域间路由,在现实世界中用于代替 classful(我们在您的示例中使用的)。我们在这里使用它只是因为它可以让我们轻松计算出我们的子网 ID。
CIDR 表示法类似于 (16.0.0.0/8),其中“/8”表示掩码中 1 的数量。因此,对于完整地址,我们从 classful 子网掩码中传递 1 的数量,即 8。
这个 python 库有一个名为“子网”的函数,它可以完全满足您的问题。您在这里唯一需要知道的是“prefixlen_diff”参数。这个参数基本上是说为我们的子网 ID 保留了多少位。这将等于我们的 classful 掩码中 1 的数量从我们的子网掩码中减去(如上所述)。
更清楚地总结一下:
网络IP地址:16.0.0.0
分类掩码: 255.0.0.0 (11111111.00000000.00000000.00000000)
Classful Mask 1's: 8
网络 IP CIDR 表示法: 16.0.0.0/8
然后对于子网:
子网掩码: 255.255.128.0 (11111111.11111111.10000000.00000000)
子网掩码中的 1: 17
1 的唯一子网掩码: 9 (00000000.11111111.10000000.00000000)
都适用于这行代码:
output = list(fullAddress.subnets(prefixlen_diff=(subnetMaskBits-classfulMaskBits)))
其中 fullAddress 是“16.0.0.0/8”,prefixlen_diff 是 9 (17 - 8)。
我们调用带有列表的子网方法来迭代出所有可能的子网 ID。我们实际上根本不需要 octetInterest 或 magicNumber 变量。
希望我回答了你想问的问题,但如果你正在寻找不同类型的输出,我可以根据需要编辑它。