首先,我们如果将每一个IP地址看做一粒沙子的话,不妨将所有的IP地址依次排列在一个横轴上,那么,IP段就可以看做这个横轴上的一个区间段。
根据子网掩码的定义,理论上,合法IP段中所包含的IP地址数量只可能是1、2、4、8、16、32、64、128……(2的n次方,n≥0)。
子网掩码对应CIDR值
所以,对于任意两个合法IP段,在这个横轴上不会存在“部分相交”的可能,而只可能是“相等”、“真包含”或者“完全不相交”这三种关系中的一种。
首先,对于两个IP段是否“相等“的情况,这个很好判断。
不妨将IP段格式写做:ipAddr/maskBit,其中,ipAddr为IP地址,maskBit为子网掩码位数,令mask为maskBit展开之后的子网掩码(公式就略过了)。
那么,在这个横轴上,maskBit实际决定了IP区间段的宽度,ipAddr则实际决定了这个IP区间段的相对位置。
根据计算机基础知识,一个IP地址由高位的网络地址和低位的主机地址构成,对ipAddr和mask进行与运算(ipAddr & mask),即可得到网络地址。
显然网络地址就位于这个IP区间段的最左侧!
因此,要判断两个IP段是否“相等“,只需要同时满足下面两个条件即可:
- 子网掩码位数maskBit相同
- 网络地址(ipAddr & mask)相同
接下来讨论“真包含”这种情况。
很显然,只可能是宽的IP区间段去包含窄的IP区间段。
我们知道,子网掩码位数越大则IP区间段越窄,所以,在子网掩码位数不相等的情况下,我们所要解决的问题实际上就转换成了:
子网掩码位数较大的那个IP地址,是否属于子网掩码位数较小的那个IP地址段?
这个问题那就好办多了……
不妨令:
子网掩码位数较大的那个IP地址段的IP地址为ipAddr1;
子网掩码位数较小的那个IP地址段的IP地址为ipAddr2,子网掩码为mask2。
那么:
只要
(ipAddr1 & mask2) == (ipAddr2 & mask2)
成立,就说明包含关系成立!
证毕。
PS:不管对于IPv4地址还是IPv6地址,上面的思路都适用!