From bf25ac607091424b85834c72aba064763aca6e54 Mon Sep 17 00:00:00 2001 From: Roger Hardiman Date: Sun, 7 Aug 2022 08:29:28 +0100 Subject: [PATCH] Adds a function to generate a range of IPv4 or IPv6 IP addresses in an array --- README.md | 5 ++++- lib/ip.js | 39 +++++++++++++++++++++++++++++++++++++++ test/api-test.js | 23 +++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 22e5819..efadbb1 100644 --- a/README.md +++ b/README.md @@ -58,10 +58,13 @@ ip.cidrSubnet('192.168.1.134/26') // range checking ip.cidrSubnet('192.168.1.134/26').contains('192.168.1.190') // true - // ipv4 long conversion ip.toLong('127.0.0.1'); // 2130706433 ip.fromLong(2130706433); // '127.0.0.1' + +// generate range +ip.range('192.168.0.1', '192.168.0.4'); // ['192.168.0.1', '192.168.0.2', '192.168.0.3', '192.168.0.4'] +ip.range('::1', '::4'); // ['::1', '::2', '::3', '::4'] ``` ### License diff --git a/lib/ip.js b/lib/ip.js index 4b2adb5..a12395e 100644 --- a/lib/ip.js +++ b/lib/ip.js @@ -420,3 +420,42 @@ ip.fromLong = function (ipl) { ipl >> 8 & 255}.${ ipl & 255}`); }; + + + +ip.range = function(start, end) { + let range = []; + if (this.isV4Format(start) && this.isV4Format(end)) { + let a = ip.toLong(start); + let b = ip.toLong(end); + for (let i = a; i <= b; i++) { + range.push(ip.fromLong(i)); + } + } + else { + let a = ip.toBuffer(start); + let b = ip.toBuffer(end); + // check same format + if (a.length === b.length) { + // while a <= b + while (Buffer.compare(a, b) <= 0) { + range.push(ip.toString(a)); + + // increment with carry + let increment = true; + let p = a.length - 1; + while (p >= 0 && increment) { + if (a[p] === 255) { + a[p] = 0; + increment = true; + } else { + a[p]++; + increment = false; + } + p--; + } + } + } + } + return range; +}; diff --git a/test/api-test.js b/test/api-test.js index f0fd222..a30b438 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -413,4 +413,27 @@ describe('IP library for node.js', () => { assert.equal(ip.fromLong(4294967295), '255.255.255.255'); }); }); + + describe('range() method', function() { + it('should respond with array of ipv4 addresses', () => { + let range_array = ip.range('192.168.0.0', '192.168.1.255'); + assert.equal(range_array.length, 512); + assert.equal(range_array[0], '192.168.0.0'); + assert.equal(range_array[1], '192.168.0.1'); + assert.equal(range_array[510], '192.168.1.254'); + assert.equal(range_array[511], '192.168.1.255'); + }); + }); + + describe('range() method', function() { + it('should respond with array of ipv6 addresses', () => { + let range_array = ip.range('2000::fffe', '2000::1:2'); + assert.equal(range_array.length, 5); + assert.equal(range_array[0], '2000::fffe'); + assert.equal(range_array[1], '2000::ffff'); + assert.equal(range_array[2], '2000::1:0'); + assert.equal(range_array[3], '2000::1:1'); + assert.equal(range_array[4], '2000::1:2'); + }); + }); });