检查网关地址是否在IP子网内

问题描述 投票:0回答:1

我正在尝试确定网关地址是否与另一个 IP 地址位于同一子网。

我使用的代码是:

var ip2long = function( ip ){
  var components;
    
  if ( components = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) ) {
    var iplong = 0;
    var power  = 1;
    for ( var i=4; i>=1; i-=1 ) {
      iplong += power * parseInt( components[i] );
      power  *= 256;
    }
    return iplong;
  }
  else return -1;
}
    
var inSubNet = function( ip, subnet ) {   
  var mask, base_ip, long_ip = ip2long(ip);
  if ( ( mask = subnet.match(/^(.*?)\/(\d{1,2})$/) ) && ( ( base_ip=ip2long( mask[1] ) ) >= 0) ) {
    var freedom = Math.pow(2, 32 - parseInt(mask[2]));
    return (long_ip > base_ip) && (long_ip < base_ip + freedom - 1);
  }
  else return false;
}

ipaddress = '192.168.10.20'
gateway = '192.168.250.1'
mask = '16'

console.log(inSubNet( ipaddress, gateway + '/' +  mask ));

对于所使用的值返回 false。 如果我更改子网,使第三个八位字节为 10 或更低,那么它就可以工作。如果是 11 或更多则返回 false。

如果我正确理解了子网,我预计任何网关地址 192.168.x.x 都会返回 true。

有人可以建议我如何做到这一点吗?

谢谢

javascript subnet
1个回答
0
投票

您可以简单地使用 AND 与子网掩码并比较八位字节。

ipaddress = '192.168.10.20'
gateway = '192.168.250.1'
mask = '16'

console.log(inSubNet(ipaddress, gateway,  bitmaskToSubnetmask(+mask)));

function bitmaskToSubnetmask(bitmask) {
  const octets = [];
  for (let i = 0; i < 4; ++i) {
    const bits = Math.min(Math.max(0, (bitmask - (i * 8))), 8);
    octets[i] = parseInt('1'.repeat(bits) + '0'.repeat(8 - bits), 2);
  }
  return octets.join('.');
}

function inSubNet(ipaddress, gateway,  subnetmask) {
  const ipaddressOctets = ipaddress.split('.').map(i => +i);
  const gatewayOctets = gateway.split('.').map(i => +i);
  const subnetmaskOctets = subnetmask.split('.').map(i => +i);
  
  for (let i = 0; i < 4; ++i) {
    if ((ipaddressOctets[i] & subnetmaskOctets[i]) !== (gatewayOctets[i] & subnetmaskOctets[i]))
      return false;
  }
  return true;
}

© www.soinside.com 2019 - 2024. All rights reserved.