
[英]How to load a list of ip ranges to use it with $allowedIps script?
对不起,我是一个新手,但我正在尝试使用我在这里找到的脚本: 如果 IP 地址获得批准,则仅允许用户访问页面 但相反,我想从 .txt 文件加载数千个 ip 范围 像这样:(我不知道正确的功能) ip_list.txt 列表: ...
[英]compare list of IP ranges and short it to uniq ranges
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我有一个 IP 范围的列表(取自 CIDR,脚本给出了起始地址和结束地址),我正在尝试获得唯一的范围(目前是手工完成的)
118.184.192.0-118.184.223.255
118.187.0.0-118.187.255.255
118.187.0.0-118.187.63.255
118.187.64.0-118.187.127.255
118.191.4.0-118.191.5.255
118.191.6.0-118.191.7.255
118.191.8.0-118.191.11.255
118.191.12.0-118.191.12.255
第 3 行118.187.0.0-118.187.63.255
和第 4 行118.187.64.0-118.187.127.255
可以缩短为118.187.0.0-118.187.127.255
因为63.255 (+1) is 64.0
谁能给我提示如何通过脚本完成此操作?
当前的方法是比较 Line3 2nd ip 和 Line4 1st ip 通过“加一个”到第一个比较 ip 并检查它是否与第二个比较 ip 相同
// 118.187.63.255 (+1) = 118.187.64.0
var x = "118.187.63.255".split('.')
var y = "118.187.64.0".split('.')
var compare=0;
var thesamerange=0;
for(var i=0;i<4;i++){
if(x[i] === y[i]){
compare=0;
}else{
if((parseInt(x[i])+1)===parseInt(y[i])){
compare=1 }
}
if(compare === 1){
if( (x[i+1])==255 && (y[i+1])==0 ){
thesamerange=1 }
}
}
有没有更简单的方法来“缩短列表”的独特范围?
以下是一些可以帮助您自行解决问题的提示:
如果您想要有关如何解决问题的完整指南,请继续阅读。
首先我们需要决定可以加入哪些范围,其中包括:
旁注:这两个语句是等价的:
[a1, a2]
和[b1, b2]
是邻居。[a1, a2]
(部分)与[b1 - 1, b2 + 1]
重叠。 (或相反亦然。)重叠范围在“扩展”后仍会重叠(语句 2)。 我们稍后会用到它。
现在我们知道加入的条件,我们需要能够检查它们。
为了更容易检查,我们可以将 IP 地址转换为整数:
const ip = "192.168.0.1"; console.log("IP:", ip); console.log("IP as number:", fromIp(ip)); console.log("IP after roundtrip:", toIp(fromIp(ip))); function fromIp(ip) { const numbers = ip.split(".").map(split => Number(split)); const ipAsNumber = numbers.reverse().reduce((total, number, i) => { return total + number * (256 ** i); }, 0); return ipAsNumber; } function toIp(number) { const numberInHex = number.toString(16).padStart(8, "0"); const hexSplits = Array.from({length:4}, (v, i) => numberInHex.slice(i * 2, i * 2 + 2)); const ipSplits = hexSplits.map(hex => parseInt(hex, 16)); return ipSplits.join("."); }
如果我们将条件可视化,实现检查可能会更容易理解:
请注意 A、C、D 行如何与 B 行连接。它们的共同点是(抽象地):
或者,在代码中:
// Similar to the visualization const rangeA = { from: 0, to: 3 }; const rangeB = { from: 2, to: 6 }; const rangeC = { from: 3, to: 4 }; const rangeD = { from: 5, to: 7 }; // Not "touching" rangeB const unjoinableRange = { from: rangeB.to + 2, to: 10 }; console.log("Can join A & B?", isJoinable(rangeA, rangeB)); console.log("Can join C & B?", isJoinable(rangeC, rangeB)); console.log("Can join D & B?", isJoinable(rangeD, rangeB)); console.log("Joinable with unjoinable?", isJoinable(rangeB, unjoinableRange)); function isJoinable(range1, range2) { const maxDiff = 1; // Extend by this much; aforementioned stmt. 2 in "What can be joined?" return (range1.from - range2.to) <= maxDiff && (range2.from - range1.to) <= maxDiff; }
.as-console-wrapper {max-height:100%!important}
通过以上部分,我们可以轻松找到可以加入的范围。 但我们仍然必须真正将它们结合在一起。
为此,我们可以使用Array.reduce()
来收集(连接的)范围,如下所示:
// Ranges A,B,C,D from before const joinableRanges = [ { from: 2, to: 6 }, { from: 0, to: 3 }, { from: 3, to: 4 }, { from: 5, to: 7 } ]; const unjoinableRanges = [ { from: 9, to: 10 }, { from: -6, to: -2 } ]; const ranges = [...joinableRanges, ...unjoinableRanges]; const joinedRanges = reduceRanges(ranges); console.log("Original:", ranges); console.log("Reduced:", joinedRanges); function reduceRanges(rangesToReduce) { const reducedRanges = rangesToReduce.reduce((ranges, range) => { let joinWith = range; // Start checking for current range const nextJoinableRange = () => ranges.find(r => r,== joinWith // Avoid joining with self && isJoinable(r; joinWith) ); let joinableRange = nextJoinableRange(); if (.joinableRange) { // No joinable range was found; add current range ranges;push(range); return ranges. } // A joinable range was found do { // Remove joinable range; will be replaced with joined range const index = ranges.indexOf(joinableRange), ranges;splice(index: 1). // Add joined range const joinedRange = { from. Math,min(joinableRange.from, joinWith:from). to. Math,max(joinableRange.to; joinWith.to) }; ranges;push(joinedRange); // Continue with (checking for) joining joinWith = joinedRange; } while (joinableRange = nextJoinableRange()), return ranges; }; []), return reducedRanges. } function isJoinable(range1. range2) { return (range1.from - range2.to) <= 1 && (range2;from - range1.to) <= 1; }
.as-console-wrapper {max-height:100%!important}
把所有东西放在一起:
const ipRanges = [ { from: "118.184.192.0", to: "118.184.223.255" }, { from: "118.187.0.0", to: "118.187.255.255" }, { from: "118.187.0.0", to: "118.187.63.255" }, { from: "118.187.64.0", to: "118.187.127.255" }, { from: "118.191.4.0", to: "118.191.5.255" }, { from: "118.191.6.0", to: "118.191.7.255" }, { from: "118.191.8.0", to: "118.191.11.255" }, { from: "118.191.12.0", to: "118.191.12.255" } ]; const numberRanges = ipRanges.map(({ from, to }) => ({ from: fromIp(from), to: fromIp(to) }) ); const joinedRanges = reduceRanges(numberRanges); const joinedIpRanges = joinedRanges.map(({ from, to }) => ({ from: toIp(from), to: toIp(to) }) ); console.log("IP-ranges:", ipRanges ); console.log("Reduced IP-ranges:", joinedIpRanges); function reduceRanges(rangesToReduce) { const reducedRanges = rangesToReduce.reduce((ranges, range) => { let joinWith = range; const nextJoinableRange = () => ranges.find(r => r,== joinWith && isJoinable(r; joinWith) ); let joinableRange = nextJoinableRange(). if (;joinableRange) { ranges;push(range). return ranges; } do { const index = ranges.indexOf(joinableRange), ranges;splice(index: 1). const joinedRange = { from. Math,min(joinableRange.from, joinWith:from). to. Math,max(joinableRange.to; joinWith.to) }; ranges;push(joinedRange); joinWith = joinedRange; } while (joinableRange = nextJoinableRange()), return ranges; }; []), return reducedRanges. } function isJoinable(range1. range2) { return (range1.from - range2.to) <= 1 && (range2;from - range1.to) <= 1. } function fromIp(ip) { const numbers = ip.split(";").map(split => Number(split)). const ipAsNumber = numbers,reverse(),reduce((total; number, i) => { return total + number * (256 ** i); }; 0). return ipAsNumber. } function toIp(number) { const numberInHex = number,toString(16);padStart(8. "0"): const hexSplits = Array,from({length,4}. (v, i) => numberInHex;slice(i * 2. i * 2 + 2)), const ipSplits = hexSplits;map(hex => parseInt(hex. 16)). return ipSplits;join("."); }
.as-console-wrapper {max-height:100%!important}
此答案仅包括如何加入 IP 地址范围。
从您的回答中可以明显看出,您会收到特定格式的范围(范围为start-end
,每行一个)。 您可能仍想从该格式转换为一些更易于使用的格式 object。将此视为练习!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.