我在node.js工作,我想做类似下面的伪代码......
let ip_range = [50.1.100.1, 51.1.30.1]; // Converted from a CIDR string.
let ip_address = 50.2.200.2; // Input IP address.
if(ip_address >= ip_range[0] && ip_address <= ip_range[1])
block(ip_address);
有关最快方法的任何想法吗?
我已经检出了cidr-js,它提供了CIDR转换功能,但没有提供IP地址比较功能。似乎node-ip可能是个不错的选择。
谢谢!
答案 0 :(得分:5)
我们所知道的IP地址只是32位数值的字符串表示。
通过将字符串表示转换回其数值,使用本机数字比较检查地址范围内的成员资格变得非常容易,如下面的代码所示:
var atoi = function atoi(addr) {
var parts = addr.split('.').map(function(str) {
return parseInt(str);
});
return (parts[0] ? parts[0] << 24 : 0) +
(parts[1] ? parts[1] << 16 : 0) +
(parts[2] ? parts[2] << 8 : 0) +
parts[3];
};
var checkIpaddrInRange = function checkIpaddrInRange(ipaddr, start, end) {
var num = atoi(ipaddr);
return (num >= atoi(start)) && (num <= atoi(end));
}
checkIpaddrInRange('10.0.1.1', '10.0.0.1', '10.0.2.1'); // => true
checkIpaddrInRange('10.0.3.1', '10.0.0.1', '10.0.2.1'); // => false
请参阅fiddle。
这是同样的事情,完全评论和错误检查:
/**
* Checks if ipaddr is valid.
* @property {string} ipaddr
* @throws Error
*/
var assertIsIpaddr = function assertIsIpaddr(ipaddr) {
if('string' !== typeof ipaddr && ipaddr) {
throw new Error('ipaddr must be a non-empty string');
}
var parts=ipaddr.split(/\./);
if(parts.length !== 4){
throw new Error('ipaddr must have four octets');
}
var i=0;
parts.map(function(str){
var val=parseInt(str),
octet = 4 - i++;;
if(val < 0 || val > 255){
throw new Error('octet '+octet+' must be between 0 and 255');
}
});
};
/**
* Converts an ipaddr to a 32bit integer value.
* @property {string} addr - the ipaddr to convert
* @returns {number}
*/
var atoi = function atoi(addr) {
// test for validity - will throw!
assertIsIpaddr(addr);
// convert octets to numbers
var parts = addr.split('.').map(function(str) {
return parseInt(str);
});
// construct result
var result = (parts[0] ? parts[0] << 24 : 0) + // if > 0, shift 4th octet left by 24
(parts[1] ? parts[1] << 16 : 0) + // if > 0, shift 3rd octet left by 16
(parts[2] ? parts[2] << 8 : 0) + // if > 0, shift 2nd octet left by 8
parts[3];
// note that if all octets are 255, result will overflow
// JavaScript (32bit) number to become -1, so we have to
// special case it. I think throwing an error here is a
// reasonable solution, since 255.255.255.255 is actually
// a broadcast addr.
if(result < 0) {
throw new Error('255.255.255.255 is not a legal host ipaddr');
}
return result;
};
/**
* Checks ipaddr membership within a range of ipaddrs.
* @property {string} ipaddr - ipaddr to check
* @property {string} start - the start of the ipaddr range
* @property {string} end - the end of the ipaddr range
* @returns {boolean} - true if ipaddr is between start and end (inclusive)
*/
var checkIpaddrInRange = function checkIpaddrInRange(ipaddr, start, end) {
var num = atoi(ipaddr);
return (num >= atoi(start)) && (num <= atoi(end));
}
// OK, test it out...
checkIpaddrInRange('10.0.1.1','10.0.0.1','10.0.2.1'); // => true
checkIpaddrInRange('10.0.3.1','10.0.0.1','10.0.2.1'); // => false
答案 1 :(得分:1)
使用ipaddr.js(npm i ipaddr.js
):
const ipaddr = require('ipaddr.js')
const addr = ipaddr.parse('2001:db8:1234::1')
addr.match(ipaddr.parseCIDR('2001:db8::/32')) // => true
或者:
const rangeList = {
documentationOnly: [ ipaddr.parse('2001:db8::'), 32 ],
tunnelProviders: [
[ ipaddr.parse('2001:470::'), 32 ], // he.net
[ ipaddr.parse('2001:5c0::'), 32 ] // freenet6
]
}
ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown') // => "tunnelProviders"
答案 2 :(得分:0)
这可能是一种更简单的方法,但这就是我如何接近它。
function pad(n) {
return (n.length < 3) ? pad('0' + n) : n;
}
// return a number with each part of the IP padded out to 3 digits
function convert(ip) {
return parseInt(ip.split('.').map(function (el) {
return pad(el);
}).join(''), 10);
}
// check the number against the range
function check(range, ip) {
ip = convert(ip);
return ip >= range[0] && ip <= range[1];
}
// convert the range
var range = ['50.1.100.1', '51.1.30.1'].map(function (el) {
return convert(el);
});
check(range, '51.1.20.2'); // true
check(range, '51.1.40.2'); // false
答案 3 :(得分:0)
也许是一个简短的方法
const ipAddress = '10.120.238.254';
const asNumber = ipAdress.split('.')
.map(p => parseInt(p))
.reverse()
.reduce((acc,val,i) => acc+(val*(256**i)),0)
然后比较数字