cidr-tools 12.1.2 → 12.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +57 -100
- package/package.json +15 -15
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ function parseIPv4Fast(s, end) {
|
|
|
38
38
|
if (dots !== 3 || digits === 0 || octet > 255) return -1;
|
|
39
39
|
return (num << 8 | octet) >>> 0;
|
|
40
40
|
}
|
|
41
|
+
const hostMasks4 = Int32Array.from({ length: 33 }, (_, i) => i === 32 ? -1 : (1 << i) - 1);
|
|
41
42
|
function formatIPv4Fast(n) {
|
|
42
43
|
return octetDotStrings[n >>> 24 & 255] + octetDotStrings[n >>> 16 & 255] + octetDotStrings[n >>> 8 & 255] + octetStrings[n & 255];
|
|
43
44
|
}
|
|
@@ -61,15 +62,9 @@ function parseIPv4Range(str) {
|
|
|
61
62
|
const v4num = parseIPv4Fast(str, rangeSlashIndex !== -1 ? rangeSlashIndex : str.length);
|
|
62
63
|
if (v4num === -1) return false;
|
|
63
64
|
rangeV4Prefix = rangeSlashIndex !== -1 ? parsePrefixNum(str, rangeSlashIndex) : 32;
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rangeV4End = 4294967295;
|
|
68
|
-
} else {
|
|
69
|
-
const mask = hostBits > 0 ? (1 << hostBits >>> 0) - 1 : 0;
|
|
70
|
-
rangeV4Start = (v4num & ~mask) >>> 0;
|
|
71
|
-
rangeV4End = (v4num | mask) >>> 0;
|
|
72
|
-
}
|
|
65
|
+
const mask = hostMasks4[Math.max(32 - rangeV4Prefix, 0)];
|
|
66
|
+
rangeV4Start = (v4num & ~mask) >>> 0;
|
|
67
|
+
rangeV4End = (v4num | mask) >>> 0;
|
|
73
68
|
return true;
|
|
74
69
|
}
|
|
75
70
|
function doNormalize(cidr, opts) {
|
|
@@ -84,10 +79,8 @@ function doNormalize(cidr, opts) {
|
|
|
84
79
|
if (prefixNum === -1) prefixNum = bits[version];
|
|
85
80
|
if (version === 4) {
|
|
86
81
|
const hostBits = 32 - prefixNum;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
else if (hostBits > 0) startNum = (startNum & ~((1 << hostBits >>> 0) - 1)) >>> 0;
|
|
90
|
-
const ip = formatIPv4Fast(startNum);
|
|
82
|
+
const mask = hostMasks4[Math.max(hostBits, 0)];
|
|
83
|
+
const ip = formatIPv4Fast((Number(number) & ~mask) >>> 0);
|
|
91
84
|
return hostBits > 0 || prefixPresent ? ip + prefixStrings[prefixNum] : ip;
|
|
92
85
|
}
|
|
93
86
|
const { compress = true, hexify = false } = opts || {};
|
|
@@ -122,24 +115,15 @@ function parseCidr(str) {
|
|
|
122
115
|
const prefixNum = prefixPresent ? parsePrefixNum(str, slashIndex) : 32;
|
|
123
116
|
const ip = formatIPv4Fast(v4num);
|
|
124
117
|
const prefix = prefixNumStrings[prefixNum] ?? String(prefixNum);
|
|
125
|
-
const
|
|
126
|
-
let startNum, endNum;
|
|
127
|
-
if (hostBits >= 32) {
|
|
128
|
-
startNum = 0;
|
|
129
|
-
endNum = 4294967295;
|
|
130
|
-
} else {
|
|
131
|
-
const mask = hostBits > 0 ? (1 << hostBits >>> 0) - 1 : 0;
|
|
132
|
-
startNum = (v4num & ~mask) >>> 0;
|
|
133
|
-
endNum = (v4num | mask) >>> 0;
|
|
134
|
-
}
|
|
118
|
+
const mask = hostMasks4[Math.max(32 - prefixNum, 0)];
|
|
135
119
|
return {
|
|
136
120
|
cidr: ip + prefixStrings[prefixNum],
|
|
137
121
|
ip,
|
|
138
122
|
version: 4,
|
|
139
123
|
prefix,
|
|
140
124
|
prefixPresent,
|
|
141
|
-
start: BigInt(
|
|
142
|
-
end: BigInt(
|
|
125
|
+
start: BigInt((v4num & ~mask) >>> 0),
|
|
126
|
+
end: BigInt((v4num | mask) >>> 0)
|
|
143
127
|
};
|
|
144
128
|
}
|
|
145
129
|
const ipPart = prefixPresent ? str.substring(0, slashIndex) : str;
|
|
@@ -188,12 +172,7 @@ function parseCidrLean(str) {
|
|
|
188
172
|
const hostBits = numBits - prefixNum;
|
|
189
173
|
if (version === 4) {
|
|
190
174
|
const num = Number(number);
|
|
191
|
-
|
|
192
|
-
start: 0,
|
|
193
|
-
end: 4294967295,
|
|
194
|
-
version: 4
|
|
195
|
-
};
|
|
196
|
-
const mask = hostBits > 0 ? (1 << hostBits >>> 0) - 1 : 0;
|
|
175
|
+
const mask = hostMasks4[Math.max(hostBits, 0)];
|
|
197
176
|
return {
|
|
198
177
|
start: (num & ~mask) >>> 0,
|
|
199
178
|
end: (num | mask) >>> 0,
|
|
@@ -367,13 +346,11 @@ function subtractSorted6(bases, excls) {
|
|
|
367
346
|
}
|
|
368
347
|
/** Returns an array of merged networks */
|
|
369
348
|
function mergeCidr(nets) {
|
|
370
|
-
const
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (n.version === 4) v4.push(n);
|
|
376
|
-
else v6.push(n);
|
|
349
|
+
const v4 = [], v6 = [];
|
|
350
|
+
for (const str of typeof nets === "string" ? [nets] : nets) {
|
|
351
|
+
const net = parseCidrLean(str);
|
|
352
|
+
if (net.version === 4) v4.push(net);
|
|
353
|
+
else v6.push(net);
|
|
377
354
|
}
|
|
378
355
|
const merged = [];
|
|
379
356
|
for (const part of mergeIntervalsRaw4(v4)) subparts4(part.start, part.end, merged);
|
|
@@ -382,42 +359,30 @@ function mergeCidr(nets) {
|
|
|
382
359
|
}
|
|
383
360
|
/** Returns an array of merged remaining networks of the subtraction of `excludeNetworks` from `baseNetworks`. */
|
|
384
361
|
function excludeCidr(base, excl) {
|
|
385
|
-
const baseArr = typeof base === "string" ? [base] : base;
|
|
386
|
-
const exclArr = typeof excl === "string" ? [excl] : excl;
|
|
387
362
|
const v4base = [], v6base = [];
|
|
388
363
|
const v4excl = [], v6excl = [];
|
|
389
|
-
for (const
|
|
390
|
-
const
|
|
391
|
-
if (
|
|
392
|
-
else v6base.push(
|
|
364
|
+
for (const str of typeof base === "string" ? [base] : base) {
|
|
365
|
+
const net = parseCidrLean(str);
|
|
366
|
+
if (net.version === 4) v4base.push(net);
|
|
367
|
+
else v6base.push(net);
|
|
393
368
|
}
|
|
394
|
-
for (const
|
|
395
|
-
const
|
|
396
|
-
if (
|
|
397
|
-
else v6excl.push(
|
|
369
|
+
for (const str of typeof excl === "string" ? [excl] : excl) {
|
|
370
|
+
const net = parseCidrLean(str);
|
|
371
|
+
if (net.version === 4) v4excl.push(net);
|
|
372
|
+
else v6excl.push(net);
|
|
398
373
|
}
|
|
399
374
|
const result = [];
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
const exclParts = mergeIntervalsRaw4(v4excl);
|
|
403
|
-
for (const part of subtractSorted4(baseParts, exclParts)) subparts4(part.start, part.end, result);
|
|
404
|
-
}
|
|
405
|
-
{
|
|
406
|
-
const baseParts = mergeIntervalsRaw6(v6base);
|
|
407
|
-
const exclParts = mergeIntervalsRaw6(v6excl);
|
|
408
|
-
for (const part of subtractSorted6(baseParts, exclParts)) subparts6(part.start, part.end, result);
|
|
409
|
-
}
|
|
375
|
+
if (v4base.length > 0) for (const part of subtractSorted4(mergeIntervalsRaw4(v4base), mergeIntervalsRaw4(v4excl))) subparts4(part.start, part.end, result);
|
|
376
|
+
if (v6base.length > 0) for (const part of subtractSorted6(mergeIntervalsRaw6(v6base), mergeIntervalsRaw6(v6excl))) subparts6(part.start, part.end, result);
|
|
410
377
|
return result;
|
|
411
378
|
}
|
|
412
379
|
/** Returns a generator for individual IPs contained in the networks. */
|
|
413
380
|
function* expandCidr(nets) {
|
|
414
|
-
const
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (n.version === 4) v4.push(n);
|
|
420
|
-
else v6.push(n);
|
|
381
|
+
const v4 = [], v6 = [];
|
|
382
|
+
for (const str of typeof nets === "string" ? [nets] : nets) {
|
|
383
|
+
const net = parseCidrLean(str);
|
|
384
|
+
if (net.version === 4) v4.push(net);
|
|
385
|
+
else v6.push(net);
|
|
421
386
|
}
|
|
422
387
|
if (v4.length > 0) for (const part of mergeIntervalsRaw4(v4)) {
|
|
423
388
|
let prevHigh = -1;
|
|
@@ -473,26 +438,22 @@ function overlapCidr(a, b) {
|
|
|
473
438
|
if (pa.version !== pb.version) return false;
|
|
474
439
|
return pa.start <= pb.end && pb.start <= pa.end;
|
|
475
440
|
}
|
|
476
|
-
const aArr = typeof a === "string" ? [a] : a;
|
|
477
|
-
const bArr = typeof b === "string" ? [b] : b;
|
|
478
441
|
const v4a = [], v6a = [];
|
|
479
442
|
const v4b = [], v6b = [];
|
|
480
|
-
for (const
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
483
|
-
else v6a.push(
|
|
484
|
-
}
|
|
485
|
-
for (const
|
|
486
|
-
const
|
|
487
|
-
if (
|
|
488
|
-
else v6b.push(
|
|
489
|
-
}
|
|
490
|
-
if (v4a.length > 0 && v4b.length > 0) if (v4b.length === 1) {
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
const as = v4a[0].start, ae = v4a[0].end;
|
|
495
|
-
for (const el of v4b) if (as <= el.end && el.start <= ae) return true;
|
|
443
|
+
for (const str of typeof a === "string" ? [a] : a) {
|
|
444
|
+
const net = parseCidrLean(str);
|
|
445
|
+
if (net.version === 4) v4a.push(net);
|
|
446
|
+
else v6a.push(net);
|
|
447
|
+
}
|
|
448
|
+
for (const str of typeof b === "string" ? [b] : b) {
|
|
449
|
+
const net = parseCidrLean(str);
|
|
450
|
+
if (net.version === 4) v4b.push(net);
|
|
451
|
+
else v6b.push(net);
|
|
452
|
+
}
|
|
453
|
+
if (v4a.length > 0 && v4b.length > 0) if (v4a.length === 1 || v4b.length === 1) {
|
|
454
|
+
const bIsSingle = v4b.length === 1;
|
|
455
|
+
const one = bIsSingle ? v4b[0] : v4a[0];
|
|
456
|
+
for (const el of bIsSingle ? v4a : v4b) if (one.start <= el.end && el.start <= one.end) return true;
|
|
496
457
|
} else {
|
|
497
458
|
v4a.sort(cmpV4Start);
|
|
498
459
|
v4b.sort(cmpV4Start);
|
|
@@ -503,12 +464,10 @@ function overlapCidr(a, b) {
|
|
|
503
464
|
else j++;
|
|
504
465
|
}
|
|
505
466
|
}
|
|
506
|
-
if (v6a.length > 0 && v6b.length > 0) if (v6b.length === 1) {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const as = v6a[0].start, ae = v6a[0].end;
|
|
511
|
-
for (const el of v6b) if (as <= el.end && el.start <= ae) return true;
|
|
467
|
+
if (v6a.length > 0 && v6b.length > 0) if (v6a.length === 1 || v6b.length === 1) {
|
|
468
|
+
const bIsSingle = v6b.length === 1;
|
|
469
|
+
const one = bIsSingle ? v6b[0] : v6a[0];
|
|
470
|
+
for (const el of bIsSingle ? v6a : v6b) if (one.start <= el.end && el.start <= one.end) return true;
|
|
512
471
|
} else {
|
|
513
472
|
v6a.sort(cmpV6Start);
|
|
514
473
|
v6b.sort(cmpV6Start);
|
|
@@ -536,19 +495,17 @@ function containsCidr(a, b) {
|
|
|
536
495
|
if (pa.version !== pb.version) return false;
|
|
537
496
|
return pa.start <= pb.start && pa.end >= pb.end;
|
|
538
497
|
}
|
|
539
|
-
const aArr = typeof a === "string" ? [a] : a;
|
|
540
|
-
const bArr = typeof b === "string" ? [b] : b;
|
|
541
498
|
const v4a = [], v6a = [];
|
|
542
499
|
const v4b = [], v6b = [];
|
|
543
|
-
for (const
|
|
544
|
-
const
|
|
545
|
-
if (
|
|
546
|
-
else v6a.push(
|
|
547
|
-
}
|
|
548
|
-
for (const
|
|
549
|
-
const
|
|
550
|
-
if (
|
|
551
|
-
else v6b.push(
|
|
500
|
+
for (const str of typeof a === "string" ? [a] : a) {
|
|
501
|
+
const net = parseCidrLean(str);
|
|
502
|
+
if (net.version === 4) v4a.push(net);
|
|
503
|
+
else v6a.push(net);
|
|
504
|
+
}
|
|
505
|
+
for (const str of typeof b === "string" ? [b] : b) {
|
|
506
|
+
const net = parseCidrLean(str);
|
|
507
|
+
if (net.version === 4) v4b.push(net);
|
|
508
|
+
else v6b.push(net);
|
|
552
509
|
}
|
|
553
510
|
if (v4b.length > 0) {
|
|
554
511
|
if (v4a.length === 0) return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cidr-tools",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.3",
|
|
4
4
|
"author": "silverwind <me@silverwind.io>",
|
|
5
5
|
"description": "Tools to work with IPv4 and IPv6 CIDR",
|
|
6
6
|
"keywords": [
|
|
@@ -29,23 +29,23 @@
|
|
|
29
29
|
"bun": "*"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ip-bigint": "^9.0.
|
|
32
|
+
"ip-bigint": "^9.0.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/node": "26.
|
|
36
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
37
|
-
"@vitest/coverage-v8": "4.1.
|
|
38
|
-
"eslint": "10.
|
|
39
|
-
"eslint-config-silverwind": "
|
|
35
|
+
"@types/node": "26.1.2",
|
|
36
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
37
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
38
|
+
"eslint": "10.8.0",
|
|
39
|
+
"eslint-config-silverwind": "143.0.0",
|
|
40
40
|
"jest-extended": "7.0.0",
|
|
41
|
-
"tsdown": "0.22.
|
|
42
|
-
"tsdown-config-silverwind": "
|
|
41
|
+
"tsdown": "0.22.14",
|
|
42
|
+
"tsdown-config-silverwind": "4.0.3",
|
|
43
43
|
"typescript": "6.0.3",
|
|
44
|
-
"typescript-config-silverwind": "20.0.
|
|
45
|
-
"updates": "17.
|
|
46
|
-
"updates-config-silverwind": "4.0.
|
|
47
|
-
"versions": "15.1.
|
|
48
|
-
"vitest": "4.1.
|
|
49
|
-
"vitest-config-silverwind": "11.
|
|
44
|
+
"typescript-config-silverwind": "20.0.3",
|
|
45
|
+
"updates": "17.19.2",
|
|
46
|
+
"updates-config-silverwind": "4.0.4",
|
|
47
|
+
"versions": "15.1.4",
|
|
48
|
+
"vitest": "4.1.10",
|
|
49
|
+
"vitest-config-silverwind": "11.4.0"
|
|
50
50
|
}
|
|
51
51
|
}
|