python - 如何在python中获取网络的所有可能的子网ID?
问题描述
尝试创建一个函数,该函数返回给定网络 ID、子网掩码、默认掩码、感兴趣的八位字节和幻数的所有可能子网 ID 的列表。在函数里面,我觉得有类子网掩码也必须使用,但似乎可以编写一个有用的程序。
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 寻址方法,有类和无类。由于您的示例包含有关分类子网的信息,因此我假设您要计算给定 IPv4 类和子网掩码的可能子网数。如果您正在寻找其他内容,我可以根据需要编辑答案。
处理 IPv4 地址时有 5 类(A、B、C、D、E)。每个类别在 IP 地址的第一个八位字节(前 8 位)中确定。
您可以在此处阅读有关确定 IPv4 类别的更多信息:https ://www.tutorialspoint.com/ipv4/ipv4_address_classes.htm
应该注意的是,在实际场景中不再使用有类 IP 寻址。
话虽如此,根据您提供的示例,您将如何分解这些信息。
首先是“<strong>Classful Subnet Mask”,用于确定您的 IP 地址有多少位构成该类别。用于该类的任何位都不能用于您的子网或主机 ID(主机 ID 是网络上实际的单个节点)。
然后你有你的“<strong>子网掩码”,它告诉你哪些位构成了你的子网 ID 和你的主机 ID。
最后,您有您的“<strong>Network 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)
我们知道有类子网掩码设置的位是为您的网络 ID 保留的(即不能被子网使用),我们也知道子网掩码未设置的位是为主机保留的(最后的 15 个 0)子网掩码)。
这意味着我们要计算子网掩码中的 1 中有多少是子网掩码唯一的,并且不包含在您的分类掩码中。在我们的示例中,十进制表示为“0.255.128.0”,二进制表示为“00000000.11111111.10000000.00000000”。
因此,我们有 9 位子网寻址空间,如果我们取 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' 库,我们可以很容易地解决查找所有可能子网的问题。我将发布示例代码,然后在下面进行解释。
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 代表无类域间路由,在现实世界中用于代替有类(我们在您的示例中使用的)。在这里我们使用它只是因为它可以让我们轻松计算出我们的子网 ID。
CIDR 符号看起来像这样(16.0.0.0/8),其中“/8”表示掩码中 1 的数量。因此,对于完整地址,我们从有类子网掩码中传入 1 的个数,即 8。
这个 python 库有一个名为“子网”的函数,它将完全按照您的问题进行操作。您在这里唯一需要知道的是“prefixlen_diff”参数。这个论点基本上是说为我们的子网 ID 保留了多少位。这将等于从子网掩码中减去分类掩码中 1 的数量(如上所述)。
更清楚地总结一下:
网络 IP 地址: 16.0.0.0
有类掩码: 255.0.0.0 (11111111.00000000.00000000.00000000)
经典面具 1 个: 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)。
我们用 list 调用 subnets 方法来迭代出所有可能的子网 ID。我们实际上根本不需要 octetInterest 或 magicNumber 变量。
希望我回答了您试图提出的问题,但如果您正在寻找不同类型的输出,我可以根据需要对其进行编辑。
推荐阅读
- ios - iOS 有没有 Swift 语言的 Rewarded interstitial Ad's Samples
- python - 正则表达式验证不适用于 Pandas 列中的大量数字
- elasticsearch - 同一字段的弹性搜索多个过滤器值
- python - 为什么我的代码无法获得 FFT 相位谱?
- shopify - 如何使用管理 API 在 Shopify 产品页面上显示每个位置的产品变体库存数量?
- javascript - 我编程的声音功能的gpujs问题
- wordpress - 将用户 ID 添加到 wordpress 正文类,但在 wp-admin 中
- python - 如果未下载 s3 文件,则捕获错误
- android - Android WebView DevTools 找不到 JavaScript 源码图
- node.js - 将多个值插入到 PostgreSQL 中的表的列中