给一间新办公室做网络规划时,我是按「2 的 n 次方减 2」报的预算:办公区整段划 /26,主机位 6 位,地址总数 64,可用主机数 62。上线那天负责交换机的同事问网关放哪个地址,我说可用范围打头的 192.168.1.65,他回了一句「那这条链路上就只能插 61 台」。让我把这条公式打上问号的是另一件事:两台路由器做点对点互联,链路段给的是 192.168.1.100/31,我拿同一个公式一算,2 的 1 次方减 2 等于 0,意思是这段地址一台设备都配不上,可实际两侧地址都配得进去。
错的不是算术,而是这条公式从一开始就只在一段前缀里成立。工具模板第 193 行的可用主机数是三分支:usable = prefix <= 30 ? total - 2 : (prefix === 31 ? 2 : 1)——减 2 只在前缀不大于 30 时生效,/31 直接给 2,/32 直接给 1,两个都是硬编码特例。
网络地址与广播地址各吃掉一个
把 192.168.1.100/26 拆开看整条算术链。第 190 行先定规模,total = Math.pow(2, 32 - prefix),32 减 26 剩 6 个主机位,2 的 6 次方是 64。第 189 行算网络地址不写按位与,而是 Math.floor(ip / 2^(32 - prefix)) * 2^(32 - prefix):3232235876 除以 64 向下取整再乘回来是 3232235840,还原成 192.168.1.64;广播地址在第 191 行是 net + total - 1,即 3232235903,还原成 192.168.1.127。可用主机数从 64 减 2 得 62,可用范围 192.168.1.65 ~ 192.168.1.126。
被扣掉的这两个地址各有身份:网络地址主机位全为 0,是整段在路由表里的门牌;广播地址主机位全为 1,发给它段内每台主机都要处理。二进制对照区把这件事摆得最清楚,/26 的掩码展开是 11111111.11111111.11111111.11000000,掩码中的 1 有 26 个、后面的 0 有 6 个;判断两台主机是否同段,就是拿它们分别与掩码做按位与。
图 1 64 格里中间 62 格才能分给机器
越过 /30,减 2 就不再成立
把前缀往上顶,越过 30 之后公式的另一支才起作用。逐档实测下来,33 档全部跑通、无一档报错,/0 到 /30 共 31 档走 2 的 n 次方减 2,只有 /31 与 /32 偏离:/31 明明只有 2 个地址却照样给 2,/32 只剩 1 个也给 1。
回到那条互联链路。输入 192.168.1.100/31,实测网络地址就是 192.168.1.100、广播地址 192.168.1.101,可用主机数 2、地址总数 2,可用范围两端写的正是这两个地址,掩码 255.255.255.254、反掩码 0.0.0.1,对应 RFC 3021 的点对点口径。范围不再往里收,是因为第 194、195 行的两条 prefix <= 30 走了另一支:首个可用取 net,末个取 bcast。/32 更极端,网络地址与广播地址同为 192.168.1.100,范围两端是同一个地址,可用主机数 1。
图 2 /31 与 /32 的绿条铺满了外框
常用档位对照
| 前缀 | 主机位 | 地址总数 | 可用主机数 |
|---|---|---|---|
| /20 | 12 | 4,096 | 4,094 |
| /24 | 8 | 256 | 254 |
| /25 | 7 | 128 | 126 |
| /26 | 6 | 64 | 62 |
| /27 | 5 | 32 | 30 |
| /29 | 3 | 8 | 6 |
| /30 | 2 | 4 | 2 |
| /31 | 1 | 2 | 2 |
| /32 | 0 | 1 | 1 |
最后两行是全部例外:/30 的 2 是 4 个地址去掉两端剩的可分配位,/31 的 2 是两个地址全部可用。
网关、VLAN 与少写的那个前缀
可用主机数这一格从来不含网关。第 193 行只扣网络地址与广播地址这 2 个,模板不预留网关、不预留 DHCP 池,9 行结果里也没有「网关地址」这一项,那 1 个位得读者自己减:62 个可用位里路由器拿走打头的 192.168.1.65,能插网线的只剩 61 台。划 VLAN 时前缀改一档、整段就搬家,同一个 192.168.1.100 从 /26 换成 /27,网络地址从 192.168.1.64 挪到 192.168.1.96,可用主机数从 62 掉到 30。
不带前缀的裸 IP 走第 126 行的默认补 /24:8.8.8.8 算成 8.8.8.0/24、10.0.5.130 算成 10.0.5.0/24,两条都只给 254 个可用地址,不会按自然掩码回落到 10.0.0.0/8 的 16,777,214。报错文案也各管各的分支:256.1.1.1/33 报「IPv4 前缀长度不能超过 32」,前缀越界排在 IP 合法性之前;192.168.1.100/100 报的是「前缀长度应为 0–32 的数字,例如 /24」。
「地址类型」那一行要少信一点:第 208 行传给 scopeOf 的是输入 IP,不是算出来的网络地址,所以 192.168.1.100/8 明明算出网络地址 192.0.0.0,标签仍显示「私有地址(192.168.0.0/16)」,没覆盖到的段一律回落「公网地址」。
这些边界值都是在子网掩码计算器里一档一档试出来的:它同时认 IP/前缀长度 与 IP 子网掩码 两种写法,192.168.1.100/26 和 192.168.1.100 255.255.255.192 落到同一个 192.168.1.64/26,敲一个字符就整表重算。想看位数与掩码怎么对上,可以读子网掩码与主机数是怎么对上的;八位组与十进制要单独核,用进制转换器换一遍。
Q:/26 到底能装几台机器?
模板给的是 62 台:主机位 6 位、地址总数 64,网络地址与广播地址各扣 1 个;网关再占 1 个可用位,插线只剩 61 台。
Q:/31 是不是真能配两台?
点对点链路上是的。实测可用主机数 2,范围就是 192.168.1.100 ~ 192.168.1.101,一个都不扣;/32 只剩 1 台,网络地址与广播地址同为 192.168.1.100。
Q:能把这 62 个可用 IP 列出来,或者替我把大段拆开吗?
都不行。可用主机范围只有「首个 ~ 末个」一个字符串,单次处理、没有批量入口;9 行输出里也没有「可划分几个子网」那一项,怎么切段还得人来定。
把边界记牢就够:total - 2 只在前缀不大于 30 时成立,/31 给 2、/32 给 1,而网关那 1 个位置永远在可用位里另算。报预算前先问三件事:前缀写多少、网关放不放段内、还有几台要固定地址。62 与 61 之间那台机器就是这么丢的。