如何判断网关地址是否与指定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
相关产品推荐
相关产品推荐

