我正在尝试确定网关地址是否与另一个 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。
有人可以建议我如何做到这一点吗?
谢谢
您可以简单地使用 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;
}