v0.5.159: fix aggregateCIDRs — баг с 1<<31, склеивание /32
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipwhitelist",
|
"name": "ipwhitelist",
|
||||||
"version": "0.5.158",
|
"version": "0.5.159",
|
||||||
"description": "IP WhiteList microservice for cloud provider",
|
"description": "IP WhiteList microservice for cloud provider",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+22
-10
@@ -100,23 +100,35 @@ function cidrToRange(cidr) {
|
|||||||
// Схлопывание списка CIDR в минимальный набор (для экспорта).
|
// Схлопывание списка CIDR в минимальный набор (для экспорта).
|
||||||
// Пример: 10.0.0.0/24 + 10.0.1.0/24 → 10.0.0.0/23
|
// Пример: 10.0.0.0/24 + 10.0.1.0/24 → 10.0.0.0/23
|
||||||
function aggregateCIDRs(cidrs) {
|
function aggregateCIDRs(cidrs) {
|
||||||
|
// 1. Сортируем по start, мержим смежные
|
||||||
const ranges = cidrs.map(c => cidrToRange(c)).sort((a, b) => a.start - b.start);
|
const ranges = cidrs.map(c => cidrToRange(c)).sort((a, b) => a.start - b.start);
|
||||||
const merged = [];
|
const merged = [];
|
||||||
for (const r of ranges) {
|
for (const r of ranges) {
|
||||||
const last = merged[merged.length - 1];
|
const last = merged[merged.length - 1];
|
||||||
if (last && r.start <= last.end + 1) last.end = Math.max(last.end, r.end);
|
if (last && r.start <= last.end + 1) last.end = Math.max(last.end, r.end);
|
||||||
else merged.push({ ...r });
|
else merged.push({ start: r.start, end: r.end });
|
||||||
}
|
}
|
||||||
return merged.map(r => {
|
// 2. Каждый merged range → минимальный набор CIDR
|
||||||
let start = r.start, end = r.end, cidrs = [];
|
const result = [];
|
||||||
while (start <= end) {
|
for (const r of merged) {
|
||||||
let maxMask = 32;
|
let start = r.start;
|
||||||
while (maxMask > 0 && ((start & ((1 << (32 - maxMask)) - 1)) !== 0 || (start + (1 << (32 - maxMask)) - 1) > end)) maxMask--;
|
while (start <= r.end) {
|
||||||
cidrs.push(numToIP(start) + '/' + maxMask);
|
// Ищем минимальную маску (самый широкий блок), подходящую под start и end.
|
||||||
start += (1 << (32 - maxMask));
|
// Идём от 1 до 32, запоминаем минимальную (самую широкую) подходящую.
|
||||||
|
let bestM = 32;
|
||||||
|
for (let m = 1; m <= 32; m++) {
|
||||||
|
if ((1 << (32 - m)) <= 0) continue;
|
||||||
|
const size = 1 << (32 - m);
|
||||||
|
if ((start & (size - 1)) !== 0) continue; // не выровнен
|
||||||
|
if (start + size - 1 > r.end) continue; // выходит за range
|
||||||
|
bestM = m;
|
||||||
|
break; // нашли самую широкую
|
||||||
|
}
|
||||||
|
result.push(numToIP(start) + '/' + bestM);
|
||||||
|
start += (1 << (32 - bestM));
|
||||||
}
|
}
|
||||||
return cidrs;
|
}
|
||||||
}).flat();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function numToIP(n) {
|
function numToIP(n) {
|
||||||
|
|||||||
Reference in New Issue
Block a user