介绍
在本实验中,你将通过 Linux 命令行掌握 IP 地址子网划分和二进制转换的基本技能。通过利用 Python 交互式解释器,你将获得对计算机网络基础计算的实践经验,将理论知识转化为终端环境中的实际应用。
你将首先把 IP 地址从熟悉的点分十进制表示法转换为 32 位二进制形式,然后再转换回来。接着,本实验将指导你将 CIDR 子网掩码转换为其二进制和点分十进制等效形式。最后,你将运用这些技能来识别给定 IP 地址的网络部分和主机部分,并计算特定 CIDR 块内可用的总主机数和子网数。
在 Python 中执行 IP 和子网掩码转换
在本步骤中,你将使用 Python 交互式解释器执行几项关键的网络转换。你将学习如何将 IP 地址在点分十进制和二进制格式之间进行转换,以及如何将 CIDR 子网掩码转换为其完整的二进制和点分十进制表示。所有这些操作都将在一个连续的会话中完成,以简化流程。
IPv4 地址是一个 32 位数字。为了方便人类阅读,它被表示为四个 8 位数字,称为字节(octets),用点分隔(例如 192.168.1.10)。这些字节中的每一个都可以转换为一个 8 位二进制数字。
首先,让我们打开终端并启动 Python 交互式解释器。LabEx 环境已预装 Python。输入
python3并按 Enter 键。python3你将看到一个新的提示符
>>>,这表示你现在已进入 Python 解释器。Python 3.10.x (...) Type "help", "copyright", "credits" or "license" for more information. >>>
将 IP 地址从点分十进制转换为二进制
让我们练习将单个十进制数转换为其二进制形式。我们将使用 Python 内置的
bin()函数。例如,要转换数字192,请在 Python 提示符下输入以下内容:bin(192)Python 将返回二进制表示,并带有
0b前缀,表示这是一个二进制数字。'0b11000000'192的二进制等效值为11000000。现在,让我们将其应用于完整的 IP 地址,例如
192.168.1.10。我们需要单独转换每个字节(192、168、1和10)。IP 地址的一个关键规则是,每个字节必须精确地表示为 8 位。如果二进制数少于 8 位,则必须添加前导零进行填充。让我们转换每个部分:
- 对于
192:bin(192)返回'0b11000000'。这已经是 8 位:11000000。 - 对于
168:bin(168)返回'0b10101000'。这也已经是 8 位:10101000。 - 对于
1:bin(1)返回'0b1'。我们必须将其填充到 8 位:00000001。 - 对于
10:bin(10)返回'0b1010'。我们必须将其填充到 8 位:00001010。
将这些组合起来,你就得到了 IP 地址
192.168.1.10的完整 32 位二进制表示:11000000.10101000.00000001.00001010- 对于
将二进制 IP 地址转换回点分十进制
现在我们将执行反向操作。要将二进制数转换为十进制数,我们将使用 Python 的
int()函数。此函数可以接受两个参数:第一个是数字的字符串表示,第二个是该数字的基数。由于我们是从二进制(基数为 2)进行转换,我们将始终使用2作为第二个参数。让我们尝试将单个二进制字节
10101000转换为十进制。int('10101000', 2)Python 将执行转换并显示十进制结果。
168现在,让我们转换上一步中的完整 32 位二进制 IP 地址:
11000000.10101000.00000001.00001010。你需要逐个转换每个 8 位字节。- 转换第一个字节:
int('11000000', 2)结果为192。 - 转换第二个字节:
int('10101000', 2)结果为168。 - 转换第三个字节:
int('00000001', 2)结果为1。 - 转换第四个字节:
int('00001010', 2)结果为10。
将这些结果用点组合起来,你就得到了原始的点分十进制 IP 地址:
192.168.1.10。这证实了你双向转换的正确性。- 转换第一个字节:
将 CIDR 子网掩码转换为其二进制和点分十进制形式
子网掩码是一个 32 位数字,用于区分 IP 地址的网络部分和主机部分。CIDR(无类别域间路由)表示法是一种表示子网掩码的简写方式。
例如,CIDR 表示法 /24 意味着 32 位子网掩码的前 24 位是 1,其余位是 0。
让我们确定
/24子网掩码的二进制和点分十进制表示。- 二进制:
/24掩码有 24 个连续的1,后跟32 - 24 = 8个0。将其分解为字节后,如下所示:11111111.11111111.11111111.00000000
- 二进制:
现在,让我们将此二进制掩码转换为其点分十进制形式。第一个字节全为
1,即11111111。int('11111111', 2)输出将是
255。最后一个字节全为零,即00000000。int('00000000', 2)输出将是
0。因此,/24子网掩码在点分十进制表示法中是255.255.255.0。让我们尝试一个更复杂的例子,例如
/26。- 二进制:
/26掩码有 26 个1,后跟32 - 26 = 6个0。11111111.11111111.11111111.11000000 - 前三个字节全为
1,我们知道这等于255。让我们将最后一个字节11000000转换为十进制。
int('11000000', 2)输出将是
192。因此,/26子网掩码在点分十进制表示法中是255.255.255.192。- 二进制:
完成转换后,你可以通过输入
exit()并按 Enter 键来退出 Python 解释器,返回到常规终端提示符。exit()
你现在已经掌握了点分十进制和二进制 IP 地址以及 CIDR 子网掩码之间的双向转换,这是任何网络专业人士的关键技能。
识别 IP 地址的网络部分和主机部分
在本步骤中,你将运用子网掩码的知识来识别给定 IP 地址的网络部分和主机部分。子网掩码的主要功能是告知计算机 IP 地址的哪一部分标识网络,哪一部分标识该网络上的特定设备(主机)。
这是通过按位逻辑 AND 操作实现的。计算机获取 IP 地址(二进制形式)和子网掩码(二进制形式),然后对它们执行 AND 操作。结果就是 网络地址。
按位 AND 的规则很简单:
1 AND 1 = 11 AND 0 = 00 AND 1 = 00 AND 0 = 0
本质上,只有当两个对应位都为 1 时,结果才为 1。
让我们用一个实际的例子来演示这一点。我们将确定 IP 地址 192.168.1.74 和 /26 子网掩码(255.255.255.192)的网络地址。我们不直接在解释器中手动操作,而是编写一个小型 Python 脚本来执行计算。
首先,使用
nano编辑器在你的项目目录中创建一个名为network_calc.py的新 Python 脚本文件。nano ~/project/network_calc.py在
nano编辑器中,复制并粘贴以下 Python 代码。此脚本定义了 IP 和掩码,对每个字节执行AND操作,并打印结果。## Define the IP address and subnet mask octets ip = [192, 168, 1, 74] mask = [255, 255, 255, 192] ## Calculate the network address using a bitwise AND network_addr = [ip[i] & mask[i] for i in range(4)] ## Format the output strings ip_str = ".".join(map(str, ip)) network_str = ".".join(map(str, network_addr)) print(f"IP Address: {ip_str}") print(f"Subnet Mask: /26 (255.255.255.192)") print(f"Network Address: {network_str}")保存文件并按
Ctrl+O,然后按Enter,最后按Ctrl+X退出nano。现在,从终端运行你的脚本。
python3 ~/project/network_calc.py你将看到以下输出,它清楚地显示了
AND操作的结果:IP Address: 192.168.1.74 Subnet Mask: /26 (255.255.255.192) Network Address: 192.168.1.64
从这个输出中,我们可以识别出不同的部分:
- 网络部分:
/26掩码表示前 26 位是网络部分。计算出的Network Address(192.168.1.64)是此特定网络的标识符。 - 主机部分: 剩余的
32 - 26 = 6位是主机部分。这 6 位标识了192.168.1.64网络内的特定设备(.74)。
你已成功使用脚本查找了网络地址,现在可以从概念上区分 IP 地址的网络部分和主机部分了。
计算给定 CIDR 的可用主机和子网数量
在最后这个步骤中,你将学习如何执行两个重要的子网划分计算:确定子网内可用主机 IP 地址的数量,以及找出如何从更大的网络块创建多少个子网。这些计算对于网络规划和设计至关重要。
以下是关键公式:
- 可用主机数量: 公式为
2^n - 2,其中n是主机位的数量(子网掩码中的0)。我们减去 2 是因为子网中的第一个地址(所有主机位都为 0)被保留为网络地址,最后一个地址(所有主机位都为 1)被保留为广播地址。两者都不能分配给设备。 - 子网数量: 当你将一个更大的网络(例如
/24)划分为更小的网络(例如/26)时,就会计算这个数量。公式为2^m,其中m是你从原始主机部分“借用”的位数,以创建新的、更具体的子网掩码。
让我们来改进我们的 network_calc.py 脚本,让它为我们执行这些计算。
首先,再次使用
nano编辑器打开network_calc.py文件。nano ~/project/network_calc.py删除现有内容,并用以下 Python 代码替换。这个新版本侧重于根据给定的 CIDR 前缀计算主机和子网计数。
## Define the CIDR prefix and the base network prefix cidr_prefix = 26 base_prefix = 24 ## The original network we are subnetting from (e.g., a /24) ## --- Calculations --- ## 1. Calculate host bits host_bits = 32 - cidr_prefix ## 2. Calculate usable hosts ## The ** operator is for exponentiation (power of) if host_bits > 0: total_hosts = 2**host_bits usable_hosts = total_hosts - 2 else: total_hosts = 1 usable_hosts = 1 ## For /31 and /32, rules are different, but we simplify here ## 3. Calculate subnet bits borrowed subnet_bits = cidr_prefix - base_prefix ## 4. Calculate number of subnets if subnet_bits >= 0: num_subnets = 2**subnet_bits else: num_subnets = "N/A (Prefix is smaller than base)" ## --- Output --- print(f"--- Subnet Calculations for a /{cidr_prefix} Network ---") print(f"Host Bits: {host_bits}") print(f"Total Hosts per Subnet: 2^{host_bits} = {total_hosts}") print(f"Usable Hosts per Subnet: {total_hosts} - 2 = {usable_hosts}") print("") ## Adds a blank line for readability print(f"--- Subnetting from a /{base_prefix} Network ---") print(f"Subnet Bits Borrowed: {subnet_bits}") print(f"Number of Subnets Created: 2^{subnet_bits} = {num_subnets}")保存文件并按
Ctrl+O,然后按Enter,最后按Ctrl+X退出nano。从终端运行更新后的脚本。
python3 ~/project/network_calc.py脚本现在将输出计算出的值:
--- Subnet Calculations for a /26 Network --- Host Bits: 6 Total Hosts per Subnet: 2^6 = 64 Usable Hosts per Subnet: 64 - 2 = 62 --- Subnetting from a /24 Network --- Subnet Bits Borrowed: 2 Number of Subnets Created: 2^2 = 4
此输出清楚地表明,对于一个 /26 网络,有 6 个主机位,允许 2^6 = 64 个总地址。在保留网络地址和广播地址后,你还剩下 62 个可用主机。它还表明,如果你从一个 /24 网络开始,你借用了 2 位来创建 /26 掩码,这会产生 2^2 = 4 个可能的子网。
总结
在本实验中,你学习了如何在 Linux 终端中直接执行基本的 IP 地址和子网划分计算。你利用 Python 交互式解释器作为一个强大的工具,将 IP 地址从人类可读的点分十进制格式转换为其 32 位二进制等效格式,然后再转换回来。这包括单独转换每个八位字节,并确保正确的 8 位填充。你还练习了将 CIDR 子网掩码表示法转换为其完整的二进制和点分十进制形式。
在这些转换技能的基础上,你将它们应用于重要的网络分析任务。你学会了如何使用子网掩码来区分 IP 地址的网络部分和主机部分。最后,你执行了必要的计算,以确定基于给定 CIDR 前缀的网络可用的主机地址数量和总子网数量,从而巩固了你对 IP 子网划分原理的理解。



