cidr-tools 11.0.13 → 11.2.0
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 +305 -118
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -108,14 +108,14 @@ function parseCidrLean(str) {
|
|
|
108
108
|
if (prefixNum === -1) prefixNum = 32;
|
|
109
109
|
const hostBits = 32 - prefixNum;
|
|
110
110
|
if (hostBits >= 32) return {
|
|
111
|
-
start:
|
|
112
|
-
end:
|
|
111
|
+
start: 0,
|
|
112
|
+
end: 4294967295,
|
|
113
113
|
version: 4
|
|
114
114
|
};
|
|
115
115
|
const mask = hostBits > 0 ? (1 << hostBits >>> 0) - 1 : 0;
|
|
116
116
|
return {
|
|
117
|
-
start:
|
|
118
|
-
end:
|
|
117
|
+
start: (v4num & ~mask) >>> 0,
|
|
118
|
+
end: (v4num | mask) >>> 0,
|
|
119
119
|
version: 4
|
|
120
120
|
};
|
|
121
121
|
}
|
|
@@ -124,18 +124,114 @@ function parseCidrLean(str) {
|
|
|
124
124
|
if (!version) throw new Error(`Network is not a CIDR or IP: "${str}"`);
|
|
125
125
|
if (prefixNum === -1) prefixNum = bits[version];
|
|
126
126
|
const hostBits = bits[version] - prefixNum;
|
|
127
|
+
if (version === 4) {
|
|
128
|
+
const num = Number(number);
|
|
129
|
+
if (hostBits >= 32) return {
|
|
130
|
+
start: 0,
|
|
131
|
+
end: 4294967295,
|
|
132
|
+
version: 4
|
|
133
|
+
};
|
|
134
|
+
const mask = hostBits > 0 ? (1 << hostBits >>> 0) - 1 : 0;
|
|
135
|
+
return {
|
|
136
|
+
start: (num & ~mask) >>> 0,
|
|
137
|
+
end: (num | mask) >>> 0,
|
|
138
|
+
version: 4
|
|
139
|
+
};
|
|
140
|
+
}
|
|
127
141
|
const mask = hostBits > 0 ? (1n << BigInt(hostBits)) - 1n : 0n;
|
|
128
142
|
return {
|
|
129
143
|
start: number & ~mask,
|
|
130
144
|
end: number | mask,
|
|
131
|
-
version
|
|
145
|
+
version: 6
|
|
132
146
|
};
|
|
133
147
|
}
|
|
148
|
+
function bigintBitLength(n) {
|
|
149
|
+
if (n === 0n) return 0;
|
|
150
|
+
let len = 0;
|
|
151
|
+
if (n >= 18446744073709551616n) {
|
|
152
|
+
n >>= 64n;
|
|
153
|
+
len = 64;
|
|
154
|
+
}
|
|
155
|
+
while (n >= 4294967296n) {
|
|
156
|
+
n >>= 32n;
|
|
157
|
+
len += 32;
|
|
158
|
+
}
|
|
159
|
+
return len + 32 - Math.clz32(Number(n));
|
|
160
|
+
}
|
|
134
161
|
function biggestPowerOfTwo(num) {
|
|
135
162
|
if (num === 0n) return 0n;
|
|
136
|
-
return 1n << BigInt(num
|
|
163
|
+
return 1n << BigInt(bigintBitLength(num) - 1);
|
|
164
|
+
}
|
|
165
|
+
function biggestPowerOfTwo4(num) {
|
|
166
|
+
if (num === 0) return 0;
|
|
167
|
+
if (num >= 4294967296) return 4294967296;
|
|
168
|
+
return 1 << 31 - Math.clz32(num) >>> 0;
|
|
137
169
|
}
|
|
138
|
-
function
|
|
170
|
+
function subparts4(pStart, pEnd, output) {
|
|
171
|
+
if (pEnd < pStart) return;
|
|
172
|
+
if (pEnd === pStart) {
|
|
173
|
+
output.push({
|
|
174
|
+
start: pStart,
|
|
175
|
+
end: pEnd
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (pEnd - pStart === 1) {
|
|
180
|
+
if (pEnd % 2 === 0) output.push({
|
|
181
|
+
start: pStart,
|
|
182
|
+
end: pStart
|
|
183
|
+
}, {
|
|
184
|
+
start: pEnd,
|
|
185
|
+
end: pEnd
|
|
186
|
+
});
|
|
187
|
+
else output.push({
|
|
188
|
+
start: pStart,
|
|
189
|
+
end: pEnd
|
|
190
|
+
});
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const size = pEnd - pStart + 1;
|
|
194
|
+
if ((size & size - 1) === 0 && pStart % size === 0) {
|
|
195
|
+
output.push({
|
|
196
|
+
start: pStart,
|
|
197
|
+
end: pEnd
|
|
198
|
+
});
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
let biggest = biggestPowerOfTwo4(size);
|
|
202
|
+
let start;
|
|
203
|
+
let end;
|
|
204
|
+
if (size === biggest && pStart % biggest === 0) {
|
|
205
|
+
output.push({
|
|
206
|
+
start: pStart,
|
|
207
|
+
end: pEnd
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
} else if (pStart % biggest === 0) {
|
|
211
|
+
start = pStart;
|
|
212
|
+
end = start + biggest - 1;
|
|
213
|
+
} else {
|
|
214
|
+
start = Math.floor(pEnd / biggest) * biggest;
|
|
215
|
+
if (start + biggest - 1 > pEnd) {
|
|
216
|
+
start = (Math.floor(pEnd / biggest) - 1) * biggest;
|
|
217
|
+
while (start < pStart) {
|
|
218
|
+
biggest /= 2;
|
|
219
|
+
start = (Math.floor(pEnd / biggest) - 1) * biggest;
|
|
220
|
+
}
|
|
221
|
+
end = start + biggest - 1;
|
|
222
|
+
} else {
|
|
223
|
+
start = Math.floor(pEnd / biggest) * biggest;
|
|
224
|
+
end = start + biggest - 1;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (start !== pStart) subparts4(pStart, start - 1, output);
|
|
228
|
+
output.push({
|
|
229
|
+
start,
|
|
230
|
+
end
|
|
231
|
+
});
|
|
232
|
+
if (end !== pEnd) subparts4(end + 1, pEnd, output);
|
|
233
|
+
}
|
|
234
|
+
function subparts6(pStart, pEnd, output) {
|
|
139
235
|
if (pEnd < pStart) return;
|
|
140
236
|
if (pEnd === pStart) {
|
|
141
237
|
output.push({
|
|
@@ -158,58 +254,86 @@ function subparts(pStart, pEnd, output) {
|
|
|
158
254
|
});
|
|
159
255
|
return;
|
|
160
256
|
}
|
|
161
|
-
const size =
|
|
257
|
+
const size = pEnd - pStart + 1n;
|
|
258
|
+
if ((size & size - 1n) === 0n && (pStart & size - 1n) === 0n) {
|
|
259
|
+
output.push({
|
|
260
|
+
start: pStart,
|
|
261
|
+
end: pEnd
|
|
262
|
+
});
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
162
265
|
let biggest = biggestPowerOfTwo(size);
|
|
163
266
|
let start;
|
|
164
267
|
let end;
|
|
165
|
-
if (size === biggest && pStart
|
|
268
|
+
if (size === biggest && (pStart & biggest - 1n) === 0n) {
|
|
166
269
|
output.push({
|
|
167
270
|
start: pStart,
|
|
168
271
|
end: pEnd
|
|
169
272
|
});
|
|
170
273
|
return;
|
|
171
|
-
} else if (pStart
|
|
274
|
+
} else if ((pStart & biggest - 1n) === 0n) {
|
|
172
275
|
start = pStart;
|
|
173
276
|
end = start + biggest - 1n;
|
|
174
277
|
} else {
|
|
175
|
-
start = pEnd
|
|
278
|
+
start = pEnd & -biggest;
|
|
176
279
|
if (start + biggest - 1n > pEnd) {
|
|
177
|
-
start = (pEnd
|
|
280
|
+
start = (pEnd & -biggest) - biggest;
|
|
178
281
|
while (start < pStart) {
|
|
179
|
-
biggest
|
|
180
|
-
start = (pEnd
|
|
282
|
+
biggest >>= 1n;
|
|
283
|
+
start = (pEnd & -biggest) - biggest;
|
|
181
284
|
}
|
|
182
285
|
end = start + biggest - 1n;
|
|
183
286
|
} else {
|
|
184
|
-
start = pEnd
|
|
287
|
+
start = pEnd & -biggest;
|
|
185
288
|
end = start + biggest - 1n;
|
|
186
289
|
}
|
|
187
290
|
}
|
|
188
|
-
if (start !== pStart)
|
|
291
|
+
if (start !== pStart) subparts6(pStart, start - 1n, output);
|
|
189
292
|
output.push({
|
|
190
293
|
start,
|
|
191
294
|
end
|
|
192
295
|
});
|
|
193
|
-
if (end !== pEnd)
|
|
296
|
+
if (end !== pEnd) subparts6(end + 1n, pEnd, output);
|
|
194
297
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
298
|
+
function formatPart4(part) {
|
|
299
|
+
const ip = formatIPv4Fast(part.start);
|
|
300
|
+
const size = part.end - part.start + 1;
|
|
301
|
+
return `${ip}/${32 - (size <= 1 ? 0 : size >= 4294967296 ? 32 : 31 - Math.clz32(size))}`;
|
|
197
302
|
}
|
|
198
|
-
function
|
|
199
|
-
if (version === 4) {
|
|
200
|
-
const ip = formatIPv4Fast(Number(part.start));
|
|
201
|
-
const sizeNum = Number(part.end - part.start) + 1;
|
|
202
|
-
return `${ip}/${32 - (sizeNum <= 1 ? 0 : sizeNum >= 4294967296 ? 32 : 31 - Math.clz32(sizeNum))}`;
|
|
203
|
-
}
|
|
303
|
+
function formatPart6(part) {
|
|
204
304
|
const ip = stringifyIp({
|
|
205
305
|
number: part.start,
|
|
206
|
-
version
|
|
306
|
+
version: 6
|
|
307
|
+
});
|
|
308
|
+
const size = part.end - part.start + 1n;
|
|
309
|
+
return `${ip}/${128 - (size <= 1n ? 0 : bigintBitLength(size) - 1)}`;
|
|
310
|
+
}
|
|
311
|
+
function mergeIntervalsRaw4(nets) {
|
|
312
|
+
if (nets.length === 0) return [];
|
|
313
|
+
nets.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
314
|
+
const merged = [];
|
|
315
|
+
let curStart = nets[0].start;
|
|
316
|
+
let curEnd = nets[0].end;
|
|
317
|
+
for (let i = 1; i < nets.length; i++) {
|
|
318
|
+
const { start, end } = nets[i];
|
|
319
|
+
if (start <= curEnd + 1) {
|
|
320
|
+
if (end > curEnd) curEnd = end;
|
|
321
|
+
} else {
|
|
322
|
+
merged.push({
|
|
323
|
+
start: curStart,
|
|
324
|
+
end: curEnd
|
|
325
|
+
});
|
|
326
|
+
curStart = start;
|
|
327
|
+
curEnd = end;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
merged.push({
|
|
331
|
+
start: curStart,
|
|
332
|
+
end: curEnd
|
|
207
333
|
});
|
|
208
|
-
|
|
209
|
-
const hostBits = size <= 1n ? 0 : size.toString(2).length - 1;
|
|
210
|
-
return `${ip}/${bits[version] - hostBits}`;
|
|
334
|
+
return merged;
|
|
211
335
|
}
|
|
212
|
-
function
|
|
336
|
+
function mergeIntervalsRaw6(nets) {
|
|
213
337
|
if (nets.length === 0) return [];
|
|
214
338
|
nets.sort((a, b) => a.start > b.start ? 1 : a.start < b.start ? -1 : a.end > b.end ? 1 : a.end < b.end ? -1 : 0);
|
|
215
339
|
const merged = [];
|
|
@@ -234,12 +358,42 @@ function mergeIntervalsRaw(nets) {
|
|
|
234
358
|
});
|
|
235
359
|
return merged;
|
|
236
360
|
}
|
|
237
|
-
function
|
|
361
|
+
function mergeIntervals4(nets) {
|
|
238
362
|
const merged = [];
|
|
239
|
-
for (const part of
|
|
363
|
+
for (const part of mergeIntervalsRaw4(nets)) subparts4(part.start, part.end, merged);
|
|
240
364
|
return merged;
|
|
241
365
|
}
|
|
242
|
-
function
|
|
366
|
+
function mergeIntervals6(nets) {
|
|
367
|
+
const merged = [];
|
|
368
|
+
for (const part of mergeIntervalsRaw6(nets)) subparts6(part.start, part.end, merged);
|
|
369
|
+
return merged;
|
|
370
|
+
}
|
|
371
|
+
function subtractSorted4(bases, excls) {
|
|
372
|
+
if (excls.length === 0) return bases;
|
|
373
|
+
if (bases.length === 0) return [];
|
|
374
|
+
const result = [];
|
|
375
|
+
let j = 0;
|
|
376
|
+
for (const base of bases) {
|
|
377
|
+
let start = base.start;
|
|
378
|
+
const end = base.end;
|
|
379
|
+
while (j < excls.length && excls[j].end < start) j++;
|
|
380
|
+
let k = j;
|
|
381
|
+
while (k < excls.length && excls[k].start <= end && start <= end) {
|
|
382
|
+
if (excls[k].start > start) result.push({
|
|
383
|
+
start,
|
|
384
|
+
end: excls[k].start - 1
|
|
385
|
+
});
|
|
386
|
+
start = excls[k].end + 1;
|
|
387
|
+
k++;
|
|
388
|
+
}
|
|
389
|
+
if (start <= end) result.push({
|
|
390
|
+
start,
|
|
391
|
+
end
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
return result;
|
|
395
|
+
}
|
|
396
|
+
function subtractSorted6(bases, excls) {
|
|
243
397
|
if (excls.length === 0) return bases;
|
|
244
398
|
if (bases.length === 0) return [];
|
|
245
399
|
const result = [];
|
|
@@ -266,83 +420,98 @@ function subtractSorted(bases, excls) {
|
|
|
266
420
|
}
|
|
267
421
|
/** Returns an array of merged networks */
|
|
268
422
|
function mergeCidr(nets) {
|
|
269
|
-
const arr =
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
423
|
+
const arr = Array.isArray(nets) ? nets : [nets];
|
|
424
|
+
const v4 = [];
|
|
425
|
+
const v6 = [];
|
|
426
|
+
for (const s of arr) {
|
|
427
|
+
const n = parseCidrLean(s);
|
|
428
|
+
if (n.version === 4) v4.push(n);
|
|
429
|
+
else v6.push(n);
|
|
430
|
+
}
|
|
275
431
|
const merged = [];
|
|
276
|
-
for (const
|
|
432
|
+
for (const part of mergeIntervals4(v4)) merged.push(formatPart4(part));
|
|
433
|
+
for (const part of mergeIntervals6(v6)) merged.push(formatPart6(part));
|
|
277
434
|
return merged;
|
|
278
435
|
}
|
|
279
436
|
/** Returns an array of merged remaining networks of the subtraction of `excludeNetworks` from `baseNetworks`. */
|
|
280
437
|
function excludeCidr(base, excl) {
|
|
281
|
-
const baseArr =
|
|
282
|
-
const exclArr =
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
438
|
+
const baseArr = Array.isArray(base) ? base : [base];
|
|
439
|
+
const exclArr = Array.isArray(excl) ? excl : [excl];
|
|
440
|
+
const v4base = [], v6base = [];
|
|
441
|
+
const v4excl = [], v6excl = [];
|
|
442
|
+
for (const s of baseArr) {
|
|
443
|
+
const n = parseCidrLean(s);
|
|
444
|
+
if (n.version === 4) v4base.push(n);
|
|
445
|
+
else v6base.push(n);
|
|
446
|
+
}
|
|
447
|
+
for (const s of exclArr) {
|
|
448
|
+
const n = parseCidrLean(s);
|
|
449
|
+
if (n.version === 4) v4excl.push(n);
|
|
450
|
+
else v6excl.push(n);
|
|
451
|
+
}
|
|
293
452
|
const result = [];
|
|
294
|
-
|
|
295
|
-
const remaining =
|
|
453
|
+
{
|
|
454
|
+
const remaining = subtractSorted4(mergeIntervalsRaw4(v4base), mergeIntervalsRaw4(v4excl));
|
|
455
|
+
const aligned = [];
|
|
456
|
+
for (const part of remaining) subparts4(part.start, part.end, aligned);
|
|
457
|
+
for (const p of aligned) result.push(formatPart4(p));
|
|
458
|
+
}
|
|
459
|
+
{
|
|
460
|
+
const remaining = subtractSorted6(mergeIntervalsRaw6(v6base), mergeIntervalsRaw6(v6excl));
|
|
296
461
|
const aligned = [];
|
|
297
|
-
for (const part of remaining)
|
|
298
|
-
for (const p of aligned) result.push(
|
|
462
|
+
for (const part of remaining) subparts6(part.start, part.end, aligned);
|
|
463
|
+
for (const p of aligned) result.push(formatPart6(p));
|
|
299
464
|
}
|
|
300
465
|
return result;
|
|
301
466
|
}
|
|
302
467
|
function* expandCidr(nets) {
|
|
303
|
-
const
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if (byVersion[v].length === 0) continue;
|
|
311
|
-
const intervals = mergeIntervalsRaw(byVersion[v]);
|
|
312
|
-
if (v === 4) for (const part of intervals) {
|
|
313
|
-
const startNum = Number(part.start);
|
|
314
|
-
const endNum = Number(part.end);
|
|
315
|
-
for (let n = startNum; n <= endNum; n++) yield formatIPv4Fast(n);
|
|
316
|
-
}
|
|
317
|
-
else for (const part of intervals) for (let num = part.start; num <= part.end; num++) yield stringifyIp({
|
|
318
|
-
number: num,
|
|
319
|
-
version: 6
|
|
320
|
-
});
|
|
468
|
+
const arr = Array.isArray(nets) ? nets : [nets];
|
|
469
|
+
const v4 = [];
|
|
470
|
+
const v6 = [];
|
|
471
|
+
for (const s of arr) {
|
|
472
|
+
const n = parseCidrLean(s);
|
|
473
|
+
if (n.version === 4) v4.push(n);
|
|
474
|
+
else v6.push(n);
|
|
321
475
|
}
|
|
476
|
+
if (v4.length > 0) for (const part of mergeIntervalsRaw4(v4)) for (let n = part.start; n <= part.end; n++) yield formatIPv4Fast(n);
|
|
477
|
+
if (v6.length > 0) for (const part of mergeIntervalsRaw6(v6)) for (let num = part.start; num <= part.end; num++) yield stringifyIp({
|
|
478
|
+
number: num,
|
|
479
|
+
version: 6
|
|
480
|
+
});
|
|
322
481
|
}
|
|
323
482
|
/** Returns a boolean that indicates if `networksA` overlap (intersect) with `networksB`. */
|
|
324
483
|
function overlapCidr(a, b) {
|
|
325
|
-
const
|
|
326
|
-
const
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
484
|
+
const aArr = Array.isArray(a) ? a : [a];
|
|
485
|
+
const bArr = Array.isArray(b) ? b : [b];
|
|
486
|
+
const v4a = [], v6a = [];
|
|
487
|
+
const v4b = [], v6b = [];
|
|
488
|
+
for (const s of aArr) {
|
|
489
|
+
const n = parseCidrLean(s);
|
|
490
|
+
if (n.version === 4) v4a.push(n);
|
|
491
|
+
else v6a.push(n);
|
|
492
|
+
}
|
|
493
|
+
for (const s of bArr) {
|
|
494
|
+
const n = parseCidrLean(s);
|
|
495
|
+
if (n.version === 4) v4b.push(n);
|
|
496
|
+
else v6b.push(n);
|
|
497
|
+
}
|
|
498
|
+
if (v4a.length > 0 && v4b.length > 0) {
|
|
499
|
+
v4a.sort((x, y) => x.start - y.start);
|
|
500
|
+
v4b.sort((x, y) => x.start - y.start);
|
|
340
501
|
let i = 0, j = 0;
|
|
341
|
-
while (i <
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
502
|
+
while (i < v4a.length && j < v4b.length) {
|
|
503
|
+
if (v4a[i].start <= v4b[j].end && v4b[j].start <= v4a[i].end) return true;
|
|
504
|
+
if (v4a[i].end < v4b[j].end) i++;
|
|
505
|
+
else j++;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (v6a.length > 0 && v6b.length > 0) {
|
|
509
|
+
v6a.sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
|
|
510
|
+
v6b.sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
|
|
511
|
+
let i = 0, j = 0;
|
|
512
|
+
while (i < v6a.length && j < v6b.length) {
|
|
513
|
+
if (v6a[i].start <= v6b[j].end && v6b[j].start <= v6a[i].end) return true;
|
|
514
|
+
if (v6a[i].end < v6b[j].end) i++;
|
|
346
515
|
else j++;
|
|
347
516
|
}
|
|
348
517
|
}
|
|
@@ -350,33 +519,51 @@ function overlapCidr(a, b) {
|
|
|
350
519
|
}
|
|
351
520
|
/** Returns a boolean that indicates whether `networksA` fully contain all `networksB`. */
|
|
352
521
|
function containsCidr(a, b) {
|
|
353
|
-
const
|
|
354
|
-
const
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (
|
|
369
|
-
|
|
370
|
-
const maxEnd = new Array(
|
|
371
|
-
maxEnd[0] =
|
|
372
|
-
for (let i = 1; i <
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
let
|
|
522
|
+
const aArr = Array.isArray(a) ? a : [a];
|
|
523
|
+
const bArr = Array.isArray(b) ? b : [b];
|
|
524
|
+
const v4a = [], v6a = [];
|
|
525
|
+
const v4b = [], v6b = [];
|
|
526
|
+
for (const s of aArr) {
|
|
527
|
+
const n = parseCidrLean(s);
|
|
528
|
+
if (n.version === 4) v4a.push(n);
|
|
529
|
+
else v6a.push(n);
|
|
530
|
+
}
|
|
531
|
+
for (const s of bArr) {
|
|
532
|
+
const n = parseCidrLean(s);
|
|
533
|
+
if (n.version === 4) v4b.push(n);
|
|
534
|
+
else v6b.push(n);
|
|
535
|
+
}
|
|
536
|
+
if (v4b.length > 0) {
|
|
537
|
+
if (v4a.length === 0) return false;
|
|
538
|
+
v4a.sort((x, y) => x.start - y.start);
|
|
539
|
+
const maxEnd = new Array(v4a.length);
|
|
540
|
+
maxEnd[0] = v4a[0].end;
|
|
541
|
+
for (let i = 1; i < v4a.length; i++) maxEnd[i] = Math.max(v4a[i].end, maxEnd[i - 1]);
|
|
542
|
+
for (const target of v4b) {
|
|
543
|
+
let lo = 0, hi = v4a.length - 1;
|
|
544
|
+
let idx = -1;
|
|
545
|
+
while (lo <= hi) {
|
|
546
|
+
const mid = lo + hi >> 1;
|
|
547
|
+
if (v4a[mid].start <= target.start) {
|
|
548
|
+
idx = mid;
|
|
549
|
+
lo = mid + 1;
|
|
550
|
+
} else hi = mid - 1;
|
|
551
|
+
}
|
|
552
|
+
if (idx < 0 || maxEnd[idx] < target.end) return false;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (v6b.length > 0) {
|
|
556
|
+
if (v6a.length === 0) return false;
|
|
557
|
+
v6a.sort((x, y) => x.start > y.start ? 1 : x.start < y.start ? -1 : 0);
|
|
558
|
+
const maxEnd = new Array(v6a.length);
|
|
559
|
+
maxEnd[0] = v6a[0].end;
|
|
560
|
+
for (let i = 1; i < v6a.length; i++) maxEnd[i] = v6a[i].end > maxEnd[i - 1] ? v6a[i].end : maxEnd[i - 1];
|
|
561
|
+
for (const target of v6b) {
|
|
562
|
+
let lo = 0, hi = v6a.length - 1;
|
|
376
563
|
let idx = -1;
|
|
377
564
|
while (lo <= hi) {
|
|
378
565
|
const mid = lo + hi >> 1;
|
|
379
|
-
if (
|
|
566
|
+
if (v6a[mid].start <= target.start) {
|
|
380
567
|
idx = mid;
|
|
381
568
|
lo = mid + 1;
|
|
382
569
|
} else hi = mid - 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cidr-tools",
|
|
3
|
-
"version": "11.0
|
|
3
|
+
"version": "11.2.0",
|
|
4
4
|
"author": "silverwind <me@silverwind.io>",
|
|
5
5
|
"description": "Tools to work with IPv4 and IPv6 CIDR",
|
|
6
6
|
"repository": "silverwind/cidr-tools",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"@typescript/native-preview": "7.0.0-dev.20260305.1",
|
|
25
25
|
"eslint": "9.39.3",
|
|
26
26
|
"eslint-config-silverwind": "121.2.0",
|
|
27
|
-
"fast-cidr-tools": "0.3.4",
|
|
28
27
|
"jest-extended": "7.0.0",
|
|
29
28
|
"tsdown": "0.21.0",
|
|
30
29
|
"tsdown-config-silverwind": "2.0.0",
|