什么是执行简单IP地址比较的最高性能的方法?

我在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转换function,但不提供IP地址比较function。 好像node-ip可能是个不错的select。

谢谢!

我们所知道的IP地址只是32位数字值的string表示forms。

通过将string表示转换回数字值,使用本机数字比较来检查地址范围内的成员资格变得非常容易,如下面的代码所示:

 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 

看小提琴 。

这是同样的事情,完全评论和正确的错误检查:

 /** * 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 

这可能是一个更简单的方法,但这是我可以如何处理它。

 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 

DEMO