Javascript: Is Ip In One Of These Subnets?
Solution 1:
The best approach is IMO making use of bitwise operators. For example, 123.123.48.0/22
represents (123<<24)+(123<<16)+(48<<8)+0
(=2071670784; this might be a negative number) as a 32 bit numeric IP address, and -1<<(32-22)
= -1024 as a mask. With this, and likewise, your test IP address converted to a number, you can do:
(inputIP & testMask) == testIP
For example, 123.123.49.123 is in that range, as 2071671163 & -1024
is 2071670784
So, here are some tool functions:
functionIPnumber(IPaddress) {
var ip = IPaddress.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
if(ip) {
return (+ip[1]<<24) + (+ip[2]<<16) + (+ip[3]<<8) + (+ip[4]);
}
// else ... ?returnnull;
}
functionIPmask(maskSize) {
return -1<<(32-maskSize)
}
test:
(IPnumber('123.123.49.123') & IPmask('22')) == IPnumber('123.123.48.0')
yields true
.
In case your mask is in the format '255.255.252.0', then you can use the IPnumber function for the mask, too.
Solution 2:
Try this:
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;
}
elsereturn -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);
}
elsereturnfalse;
};
Usage:
inSubNet('192.30.252.63', '192.30.252.0/22') => trueinSubNet('192.31.252.63', '192.30.252.0/22') => false
Solution 3:
I managed to solve this by using the node netmask module. You can check if an IP belongs to a subnet by making something like this:
import { Netmask } from'netmask'const block = newNetmask('123.123.208.0/20')
const ip = '123.123.208.0'console.log(block.contains(ip))
Will here print true
.
You can install it by using:
npm i--save netmask
Solution 4:
Convert the lower ip and the upper ip in the range to integers and store the range in the db then make sure both columns are indexed.
Off the top of my head (pseudo code):
functionipmap(w,x,y,z) {
return16777216*w + 65536*x + 256*y + z;
}
var masks = array[ipmap(128,0,0,0), ipmap(196,0,0,0), ..., ipmap(255,255,255,255)]
functionlowrange(w, x, y, z, rangelength) {
return ipmap(w, x, y, z) & masks[rangelength]
}
functionhirange(w, x, y, z, rangelength) {
return lowrange(w, x, y, z, ,rangelength) + ipmap(255,255,255,255) - masks[rangelength];
}
That ought to do it.
To find whether a particular ip falls in any of the ranges, convert it to an integer and do:
SELECTCOUNT(*) FROM ipranges WHERE lowrange <=1234567AND1234567<= highrange
The query optimizer should be able to speed this up greatly.
Solution 5:
Functions IPnumber
and IPmask
are nice, however I would rather test like:
(IPnumber('123.123.49.123') & IPmask('22')) == (IPnumber('123.123.48.0') & IPmask('22'))
Because for each address, you only need to take into account the network part of the address. Hence doing IPmask('22')
will zero-out the computer part of the address and you should do the same with the network address.
Post a Comment for "Javascript: Is Ip In One Of These Subnets?"