You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断网关地址是否与指定IP处于同一IP子网?

问题描述

需要判断网关地址与另一IP地址是否处于同一IP子网,现有JavaScript代码如下:

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,但按/16子网规则,所有192.168.x.x的IP都应属于同一子网,需要修正代码实现正确判断。

问题根源

原代码的错误在于:它将网关IP直接当作子网的起始地址,通过计算base_ip + freedom来判断IP是否在范围内。但实际上网关IP只是子网内的一个主机地址,子网的网络地址应该是网关IP与子网掩码按位与的结果,正确的判断逻辑是比较目标IP和网关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 maskMatch, longIp = ip2long(ip);
  if ( !(maskMatch = subnet.match(/^(.*?)\/(\d{1,2})$/)) ) {
    return false;
  }
  
  var subnetIp = ip2long(maskMatch[1]);
  if (subnetIp === -1 || longIp === -1) {
    return false;
  }
  
  // 计算子网掩码的长整数:前cidr位为1,其余为0
  var cidr = parseInt(maskMatch[2]);
  var subnetMask = (0xFFFFFFFF << (32 - cidr)) >>> 0; // 无符号右移确保得到正整数
  
  // 计算两者的网络地址并比较
  var ipNetwork = longIp & subnetMask;
  var subnetNetwork = subnetIp & subnetMask;
  
  return ipNetwork === subnetNetwork;
}

// 测试案例
const ipaddress = '192.168.10.20';
const gateway = '192.168.250.1';
const mask = '16';

console.log(inSubNet(ipaddress, gateway + '/' + mask)); // 输出 true
关键修正点
  • 生成正确的子网掩码:根据CIDR位数,通过位运算生成对应的32位掩码(比如/16对应掩码0xFFFF0000)
  • 计算网络地址:将目标IP和子网基准IP分别与掩码做按位与运算,得到各自的网络地址
  • 比较网络地址:只要两者的网络地址相同,就说明处于同一子网

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 21:56:08