【计算机网络】验证两个ip是否在同一网段

今天有一个需求,要验证用户的输入ip 和 某一个环境下的ip/mask是否在同一个网段,准确的说 ip/mask表述的不准确,权威的表述是这个:Classless Inter-Domain Routing

比如用户填的是: 10.1.1.5
server端返回的ip/mask是这个10.1.1.12/24

我们先解决这个问题,我们都知道,本来ip地址是32位的二进制数来表示。为了方便我们将分成4个字节,每个字节8位,转换成十进制来显示。

10.1.1.5 转换成二进制是这样:
00001010 00000001 00000001 00000101

10.1.1.12 转换成二进制是这样:
00001010 00000001 00000001 00001100

判断是否在同一个网段的要求就是我们那这两个ip地址,与子网掩码做一次 & 与运算,然后判断结果是否是相等,相等则是属于同一网段。

10.1.1.12/24 后面这个24则标识了子网掩码(ipv4 max value is 32,ipv6 max value is 128):

11111111 11111111 11111111 00000000(32位,前24位为1)

我们需要对
00001010 00000001 00000001 00000101 (10.1.1.5)
与掩码
11111111 11111111 11111111 00000000

做一次 & 操作;


然后对
00001010 00000001 00000001 00001100 (10.1.1.12)
与掩码
11111111 11111111 11111111 00000000
做一次 & 操作。

最后的结果是一样,属于同一网段。

帮助方法:

export const checkIsInSameNetworkSegment= (ip, ipMask)=> {
  let arr = ipMask.split('/'),
    mask = arr[1],
    standardIp = arr[0]
  mask = (0XFFFFFFFF)<<(32- Number(arr[1]))
  let ips = ip.split('.').map(item=>parseInt(item)) //将ip分成4个数字组成的数组
  let crdIps = standardIp.split('.').map(item=>parseInt(item)) //将ip分成4个数字组成的数组
  let ipBinary = (ips[0]<<24) | (ips[1]<<16) | (ips[2]<<8) | (ips[3])
  let crdIpBinary = (crdIps[0]<<24) | (crdIps[1]<<16) | (crdIps[2]<<8) | (crdIps[3])
  return (ipBinary & mask) === (crdIpBinary & mask)
}

如果忘记了位运算请看这里: javascript位运算

其他资料:

网络地址分类(有些问题,请对比wiki和下面的知乎链接)

Classful network(WIKI)

子网掩码与ip地址有实际关系吗? - 回答作者: DADAman

猜你喜欢

转载自blog.csdn.net/a5534789/article/details/79259667