在 Linux 终端中执行 IP 子网划分和二进制转换

CompTIABeginner
立即练习

介绍

在本实验中,你将通过 Linux 命令行掌握 IP 地址子网划分和二进制转换的基本技能。通过利用 Python 交互式解释器,你将获得对计算机网络基础计算的实践经验,将理论知识转化为终端环境中的实际应用。

你将首先把 IP 地址从熟悉的点分十进制表示法转换为 32 位二进制形式,然后再转换回来。接着,本实验将指导你将 CIDR 子网掩码转换为其二进制和点分十进制等效形式。最后,你将运用这些技能来识别给定 IP 地址的网络部分和主机部分,并计算特定 CIDR 块内可用的总主机数和子网数。

在 Python 中执行 IP 和子网掩码转换

在本步骤中,你将使用 Python 交互式解释器执行几项关键的网络转换。你将学习如何将 IP 地址在点分十进制和二进制格式之间进行转换,以及如何将 CIDR 子网掩码转换为其完整的二进制和点分十进制表示。所有这些操作都将在一个连续的会话中完成,以简化流程。

IPv4 地址是一个 32 位数字。为了方便人类阅读,它被表示为四个 8 位数字,称为字节(octets),用点分隔(例如 192.168.1.10)。这些字节中的每一个都可以转换为一个 8 位二进制数字。

  1. 首先,让我们打开终端并启动 Python 交互式解释器。LabEx 环境已预装 Python。输入 python3 并按 Enter 键。

    python3
    

    你将看到一个新的提示符 >>>,这表示你现在已进入 Python 解释器。

    Python 3.10.x (...)
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    

将 IP 地址从点分十进制转换为二进制

  1. 让我们练习将单个十进制数转换为其二进制形式。我们将使用 Python 内置的 bin() 函数。例如,要转换数字 192,请在 Python 提示符下输入以下内容:

    bin(192)
    

    Python 将返回二进制表示,并带有 0b 前缀,表示这是一个二进制数字。

    '0b11000000'
    

    192 的二进制等效值为 11000000

  2. 现在,让我们将其应用于完整的 IP 地址,例如 192.168.1.10。我们需要单独转换每个字节(192168110)。IP 地址的一个关键规则是,每个字节必须精确地表示为 8 位。如果二进制数少于 8 位,则必须添加前导零进行填充。

    让我们转换每个部分:

    • 对于 192bin(192) 返回 '0b11000000'。这已经是 8 位:11000000
    • 对于 168bin(168) 返回 '0b10101000'。这也已经是 8 位:10101000
    • 对于 1bin(1) 返回 '0b1'。我们必须将其填充到 8 位:00000001
    • 对于 10bin(10) 返回 '0b1010'。我们必须将其填充到 8 位:00001010

    将这些组合起来,你就得到了 IP 地址 192.168.1.10 的完整 32 位二进制表示:

    11000000.10101000.00000001.00001010

将二进制 IP 地址转换回点分十进制

  1. 现在我们将执行反向操作。要将二进制数转换为十进制数,我们将使用 Python 的 int() 函数。此函数可以接受两个参数:第一个是数字的字符串表示,第二个是该数字的基数。由于我们是从二进制(基数为 2)进行转换,我们将始终使用 2 作为第二个参数。

    让我们尝试将单个二进制字节 10101000 转换为十进制。

    int('10101000', 2)
    

    Python 将执行转换并显示十进制结果。

    168
    
  2. 现在,让我们转换上一步中的完整 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

  1. 让我们确定 /24 子网掩码的二进制和点分十进制表示。

    • 二进制: /24 掩码有 24 个连续的 1,后跟 32 - 24 = 80。将其分解为字节后,如下所示: 11111111.11111111.11111111.00000000
  2. 现在,让我们将此二进制掩码转换为其点分十进制形式。第一个字节全为 1,即 11111111

    int('11111111', 2)
    

    输出将是 255。最后一个字节全为零,即 00000000

    int('00000000', 2)
    

    输出将是 0。因此,/24 子网掩码在点分十进制表示法中是 255.255.255.0

  3. 让我们尝试一个更复杂的例子,例如 /26

    • 二进制: /26 掩码有 26 个 1,后跟 32 - 26 = 6011111111.11111111.11111111.11000000
    • 前三个字节全为 1,我们知道这等于 255。让我们将最后一个字节 11000000 转换为十进制。
    int('11000000', 2)
    

    输出将是 192。因此,/26 子网掩码在点分十进制表示法中是 255.255.255.192

  4. 完成转换后,你可以通过输入 exit() 并按 Enter 键来退出 Python 解释器,返回到常规终端提示符。

    exit()
    

你现在已经掌握了点分十进制和二进制 IP 地址以及 CIDR 子网掩码之间的双向转换,这是任何网络专业人士的关键技能。

识别 IP 地址的网络部分和主机部分

在本步骤中,你将运用子网掩码的知识来识别给定 IP 地址的网络部分和主机部分。子网掩码的主要功能是告知计算机 IP 地址的哪一部分标识网络,哪一部分标识该网络上的特定设备(主机)。

这是通过按位逻辑 AND 操作实现的。计算机获取 IP 地址(二进制形式)和子网掩码(二进制形式),然后对它们执行 AND 操作。结果就是 网络地址

按位 AND 的规则很简单:

  • 1 AND 1 = 1
  • 1 AND 0 = 0
  • 0 AND 1 = 0
  • 0 AND 0 = 0

本质上,只有当两个对应位都为 1 时,结果才为 1

让我们用一个实际的例子来演示这一点。我们将确定 IP 地址 192.168.1.74/26 子网掩码(255.255.255.192)的网络地址。我们不直接在解释器中手动操作,而是编写一个小型 Python 脚本来执行计算。

  1. 首先,使用 nano 编辑器在你的项目目录中创建一个名为 network_calc.py 的新 Python 脚本文件。

    nano ~/project/network_calc.py
    
  2. 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}")
    
  3. 保存文件并按 Ctrl+O,然后按 Enter,最后按 Ctrl+X 退出 nano

  4. 现在,从终端运行你的脚本。

    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 Address192.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 脚本,让它为我们执行这些计算。

  1. 首先,再次使用 nano 编辑器打开 network_calc.py 文件。

    nano ~/project/network_calc.py
    
  2. 删除现有内容,并用以下 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}")
    
  3. 保存文件并按 Ctrl+O,然后按 Enter,最后按 Ctrl+X 退出 nano

  4. 从终端运行更新后的脚本。

    python3 ~/project/network_calc.py
    
  5. 脚本现在将输出计算出的值:

    --- 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 子网划分原理的理解。