替一間新辦公室做網路規劃時,我是照「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 行算網路位址不寫按位元 AND,而是 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 個;要判斷兩台是否同段,就是拿兩台分別跟遮罩做按位元 AND。
圖 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 之間那台機器就是這麼丟的。