掩码是「网络位全 1、主机位全 0」的一个 32 位数,它不是地址,是一把尺子。 有了掩码,分界线就不用再由「类别」决定——这是子网划分的全部内容。
4.3.2 说「分界线靠类别」,这一节说「分界线可以自己划」。 它是 CIDR 和 VLSM 的基础,也是所有内网规划的起点。
一、掩码是一把尺子
几个常用前缀的掩码:
| 前缀 | 掩码 | 块大小 | 可用主机 |
|---|---|---|---|
| /24 | 255.255.255.0 | 256 | 254 |
| /26 | 255.255.255.192 | 64 | 62 |
| /28 | 255.255.255.240 | 16 | 14 |
| /30 | 255.255.255.252 | 4 | 2 |
掩码的「1」的个数就是前缀长度: /26 意味着前 26 位是 1,写成十进制就是 255.255.255.192(因为 192 是 11000000)。 所以「掩码」和「前缀长度」是同一个东西的两种写法。 第三列的「块大小」是心算的关键:/26 是 64 一格,/28 是 16 一格, 所以「152 落在哪一格」只要除一下就知道。这比按位与快,而且不容易错。
二、用块大小心算
算 192.168.3.152/26 的网络地址,只要三步:
块大小 = 256 / 2^(26-24) = 64
152 / 64 = 2 余 24 -> 落在第 2 块(从 0 数)
网络地址 = 192.168.3.(2*64) = 192.168.3.128
广播地址 = 192.168.3.(128+64-1) = 192.168.3.191
这四行把「子网划分」的心算讲完了:块大小、取整、加偏移、减一。 其中「取整」这一步用的是整除,不是四舍五入—— 所以 152 除 64 得 2(不是 2.4 舍成 2),而 191 除 64 得 2,也在同一块里。 这套算法对任何前缀都成立:块大小等于 2 的主机位数次方, 所以 /24 是 256、/25 是 128、/27 是 32、/30 是 4。 记住这几个数,内网规划时基本不用计算器。 有一个坑要说清:「块大小」是从「最后一个掩码非 255 的那一段」算起的。 比如 /20 的掩码是 255.255.240.0,它的块大小是 16,但作用在第三段,不是第四段—— 所以「192.168.5.0/20」这种写法本身就是错的(它不对齐)。
三、/31 和 /32 两个例外
这两个前缀不符合「减 2」的习惯:
| 前缀 | 地址数 | 传统算法 | 实际用法 |
|---|---|---|---|
| /31 | 2 | 0 | RFC 3021 点对点 |
| /32 | 1 | 0 | 单主机路由 |
第一行是「两个地址、两端各一个」:点对点链路没有「本网段广播」这个概念(只有两家), 所以不需要预留网络地址和广播地址。 这样「一段 /30 只用掉 2 个可用」就变成「/31 用掉 2 个」,对运营商来说省了一半地址。 第二行是「一个地址、就是它自己」:它最常见的用途是「路由表里给某个 IP 单独指一条路」, 也就是 4.2.2 讲的「最具体的那条前缀」。 所以「/32 主机路由」这个词在运维里天天出现——它不表示「一个网段」,表示「一台机器」。 最后说清「掩码必须连续」这件事: 合法的掩码只有「前面全是 1、后面全是 0」这 33 种(0 到 32 位)。 「255.0.255.0」这种是非法掩码, 因为它中间有 0 又有 1,设备一般会拒绝配置,或者报「掩码不连续」。
四、动手 Demo:子网掩码就是把「分界线」写出来
把九个前缀的掩码、地址数、可用主机列出来,再用块大小心算一次。 注意最后两行:/31 和 /32 不按「减 2」算。
import ipaddress
for p in (24, 26, 28, 30, 31, 32):
n = 2 ** (32 - p)
mask = ipaddress.ip_network('0.0.0.0/%d' % p).netmask
print('/%-2d %-16s 地址 %3d 可用 %s'
% (p, mask, n, n - 2 if p < 31 else '见 RFC 3021'))
实跑输出:
--------------------------------------------------------------------
子网掩码就是把「分界线」写出来
--------------------------------------------------------------------
**掩码是「网络位全 1、主机位全 0」的一个 32 位数。**
**所以掩码不是「另一个地址」,它是「一把尺子」。**
前缀 掩码 地址数 可用主机
------------------------------------------------------
/24 255.255.255.0 256 254
/25 255.255.255.128 128 126
/26 255.255.255.192 64 62
/27 255.255.255.224 32 30
/28 255.255.255.240 16 14
/29 255.255.255.248 8 6
/30 255.255.255.252 4 2
/31 255.255.255.254 2 2(RFC 3021)
/32 255.255.255.255 1 1(单主机)
**最后两行要特别注意**:
**/31 只有 2 个地址,传统算法「减 2」之后是 0**——**因为它没有可分的网络地址和广播地址。**
**但 RFC 3021 把它救活了**:点对点链路两端各用一个,不要广播,正好两个。
**/32 只有 1 个地址,平时不给主机用**,
**它的典型用途是「给某一个 IP 单独指一条路由」**——**也就是路由表里那条最具体的 /32。**
**算一下掩码是怎么「切」地址的**:
**192.168.3.152/26** 的网络地址是 **192.168.3.128**,主机部分是 **24**
**验算:152 除以 64 得 2 余 24**,**所以它落在「64 的倍数」里第 2 段(128 到 191)**,
**网络地址 192.168.3.128、广播地址 192.168.3.191。**
**这套「除以块大小再取整」的心算法,比按位与快得多。**
ipaddress 的 netmask 属性给的是「点分十进制掩码」,
而 prefixlen 给的是「/26」这种长度。
两者互换很方便:
ip_network('0.0.0.0/26').netmask 和ip_network('255.255.255.192/26').prefixlen 说的是同一件事。
「/26 是 64 一格」这个换算值得背下来:
/25 是 128、/26 是 64、/27 是 32、/28 是 16、/29 是 8、/30 是 4。
这六个数覆盖了绝大多数内网规划场景。
最后一个实用提醒:配 IP 时「地址」和「掩码」必须一起给,
因为「192.168.3.152」这个数本身不包含「网络有几位」的信息。
所以「只给 IP 不给掩码」在技术上是不完整的——
很多系统会默认填一个「类别掩码」,那就容易出错了。
30 秒实验
- 算一下:192.168.3.200/27 的网络地址和广播地址分别是什么?
- 想一下:为什么「255.0.255.0」这种掩码不合法?
- 想一下:/31 为什么能省地址?
常见误区
- 以为「掩码是另一个 IP 地址」。 它是「尺子」,标记网络位到哪一位为止。
- 以为「配 IP 不用给掩码」。 必须一起给,否则不知道网络有几位。
- 以为「所有掩码都能用」。 只有「连续的前缀」合法,中间夹 0 的不行。
自测三问(点开对答案)
1. /26 的掩码和块大小是多少? —— **255.255.255.192,块大小 64**,可用主机 62 台。 2. 192.168.3.152/26 的网络地址怎么算? —— **152 除 64 取整得 2,所以网络地址是 192.168.3.128**,广播是 .191。 3. /32 有什么用? —— **给单个 IP 指一条路由**,也就是「最具体的那条前缀」。下一节看 CIDR 和 VLSM:一个往外并、一个往里切。
- ☐ (本节完,下一节 4.3.7 CIDR与VLSM)