对于我来说,划分子网总是一个悬而未悬的问题,困扰了我好几年,最近深入学习了计算机网络,总算是搞明白了这当中的关系。
# 按位与的规则 ↵
通过计算IP地址与掩码的按位与结果,可以得到IP地址的网络地址。
按位与的规则如下:(一个例子)
有一个二进制数 a 与 b 的按位与结果如下:(换成十进制就是 34,为方便高四位和低四位用
有一个二进制数 a 与 b 的按位与结果如下:(换成十进制就是 34,为方便高四位和低四位用
,
隔开)0010, 0010
这是a0000, 0010
这是b0000, 0010
a & b 的 结果如果对应位都为 1 则结果的对应位是 1,否则是 0。
按位与其实是将一位的与运算推广到多个比特位的与运算。用 JavaScript 表示就是:
00function andAll(a, b){ 01 return a.map((bit, idx) => { 02 return bit & b[idx]; 03 }); 04} 05 06var a = [0, 0, 1, 0, 0, 0, 1, 0]; 07var b = [0, 0, 0, 0, 0, 0, 1, 0]; 08 09andAll(a, b); 10// => 11// [0, 0, 0, 0, 0, 0, 1, 0]
对于本文,我们约定用
&&
来表示按位与也就是说上面的运算过程可以写成:
a && b = (0000, 0010)
# 划分子网 ↵
比如你现在拥有 IP 地址池子:
192.168.1.0 ~ 192.168.1.255
一共 256
个 IP 地址,现在有 4 个单位需要用网络,每个单位大概要 50 个地址,而且还要保证这 4 个网络又是不同的局域网 (即不能直接访问,要通过路由器)根据需求很容易得到一个可行的方案:
- 单位 A 使用 192.168.1.0 ~ 192.168.1.63
- 单位 B 使用 192.168.1.64 ~ 192.168.1.197
- 单位 C 使用 192.168.1.128 ~ 192.168.1.191
- 单位 D 使用 192.168.1.192 ~ 192.168.1.255
并且称上面四个地址区间为
a
b
c
d
# 按位与的结果就是网络地址 ↵
网络地址 = IP 地址 && 子网掩码
而 a b c d 四个地址区间共 256 个 IP 地址。
现在遍历abcd四个地址池,计算所有可能的
网络地址
,用 JavaScript 编程解决该问题的代码是:00// 按位与计算 01var andAll = (a, b) => { 02 return a.map((bit, idx) => { 03 return bit & b[idx]; 04 }) 05} 06 07// 十进制换二进制数组 便于andAll进行计算 08var toBinary = n => { 09 let arr = n.toString(2).split('').map(e => parseInt(e)); 10 11 arr = new Array(8 - arr.length).fill(0).concat(arr); 12 13 return arr; 14} 15 16// 封装 输入整数 a b 得到按位与结果 17var calcAnds = (a, b) => ( 18 andAll( 19 toBinary(a), 20 toBinary(b) 21 ).join('') 22); 23 24// 去重 工具函数 25var unique = arr => { 26 return arr.reduce((acc, cur) => { 27 if (!acc.includes(cur)) acc.push(cur); 28 29 return acc; 30 }, []) 31} 32 33// MASK 是掩码 34var main = MASK => { 35 // idx 从 0 到 255 36 // 因为前三字节掩码是 255 37 return new Array(256).fill(0).map((_, idx) => { 38 return calcAnds(idx, MASK); 39 }) 40}
调用
main
并给出 掩码 MASK
可以得到长度为 256
的网络地址的运算结果 (IP地址的最后一个字节)# 网络地址及其内涵 ↵
现在调用
main
给入不同的掩码计算结果00unique( 01 // 1100, 0000 02 main(192) // 得到 main 的时候去重 03); 04// => 05// ["00000000", "01000000", "10000000", "11000000"]
当使用 255.255.255.192 即
1100, 0000
作为掩码的时候,网络地址只有四种分别对应着四个地址区间
0 ~ 63
, 64 ~ 127
, 128 ~ 192
, 193 ~ 255
,这意味着按位与运算的结果是这个区间的 特征值
,而计算机网络把它作为网络号使用了,而且路由器也是利用网络号进行转发的。说明了网络地址的内涵在于其代表着一个掩码对应一个区间的特征值。换句话说,在某个掩码的作用下,网络地址就是子网的唯一标识符。
# 另外一个角度 ↵
说回刚刚的 192 即 1100, 0000 作为掩码的时候的情况:
因为前两位是 1 而后面的全 0,说明不论低六位怎么变,在前两位确定的情况下按位与运算结果均不变,因此从 0 到 255 按位与的结果只有四种:
0000, 0000
0100, 0000
1000, 0000
1100, 0000
而其子网掩码是
255.255.255.192
现在我们的网络就被分成上面四个子网了。# 例子 ↵
某校有 4 栋建筑物(教学楼、实验楼、宿舍、图书馆),每栋需要 200 个地址,现在学校分配给你一个IP地址
202.156.13.5/16
,请你帮忙划分一下子网。(202.156.13.5 / 16 这种IP表示方式是 CIDR ,16代表掩码里
1
的个数,这里是16所以掩码是 11111111 11111111 00000000 00000000 一共32位,换成十进制是 255.255.0.0)很容易划分。
需要划分的地址范围:
202.156.0.0
~ 202.156.255.255
共 65536 绰绰有余。如使用掩码
255.255.255.0
来进行划分,所以:-
202.156.0.0
~202.156.0.255
是一块
网络地址是202.156.0.0
-
202.156.1.1
~202.156.1.255
是一块
网络地址是202.156.1.0
-
202.156.2.0
~202.156.2.255
是一块
网络地址是202.156.2.0
-
…
-
202.156.255.0
~202.156.255.255
是一块
网络地址是202.156.255.0
因此一个可行的分配方案如下:
- 网络地址
202.156.0.0
划给教学楼 - 网络地址
202.156.1.0
划给实验楼 - 网络地址
202.156.2.0
划给宿舍 - 网络地址
202.156.3.0
划给图书馆 - 剩余地址
202.156.x.0
用于将来网络拓展
以上地点均使用掩码
255.255.255.0
,除此之外每一栋楼均需要数台交换机组成,并暴露一条线连接到校园网络中心总机路由器上以连接至外网。至此,划分结束。
