繁体   English   中英

比较 IP 范围的列表并将其缩短为 uniq 范围

[英]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 }
  }
}

有没有更简单的方法来“缩短列表”的独特范围?

以下是一些可以帮助您自行解决问题的提示:

  1. IP 地址可以完全转换为数字,反之亦然。 Java 的解释)。
  2. 通过一个端点是否包含在另一个范围中来检查范围是否重叠(应该连接)。

如果您想要有关如何解决问题的完整指南,请继续阅读。


加入范围

可以加入什么?

首先我们需要决定可以加入哪些范围,其中包括:

  • 重叠的范围:
    • 部分重叠的范围。
    • 一个是另一个的子范围的范围。
  • 端点是直接邻居的范围。 (“接触”的范围。)

旁注:这两个语句是等价的:

  1. 范围[a1, a2][b1, b2]是邻居。
  2. 范围[a1, a2] (部分)与[b1 - 1, b2 + 1]重叠。 (或相反亦然。)

重叠范围在“扩展”后仍会重叠(语句 2)。 我们稍后会用到它。

转换为更简单的类型

现在我们知道加入的条件,我们需要能够检查它们。

为了更容易检查,我们可以将 IP 地址转换为整数:

  • 从点符号
    将 IP 地址解释为 base-256 4“数字”数字,其中数字是点分隔的 integer。
  • 点符号
    1. 将数字解析为 8 位十六进制数(如有必要,带前导零)。
    2. 将每两个 base-16 数字解释为一个 base-256 数字。
    3. 将四个 base-256 数字解析为数字。
    4. 用点连接数字。

 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("."); }

如何检查可连接性

如果我们将条件可视化,实现检查可能会更容易理解:

四行表示范围(数学:间隔)。三行满足与第四行的连接条件: 1. 一个完全包含在第四行中。 2. 一个与第四个部分重叠。 3. 一个紧挨着(接触)第四个。

请注意 A、C、D 行如何与 B 行连接。它们的共同点是(抽象地):

  • 可连接线的左端位于 B 右端的左侧。
  • 可连接线的右端位于 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}

最后

把所有东西放在一起:

  1. 从 IP 地址范围转换为数字范围。
  2. 加入范围:
    1. 如果当前范围不可连接,则收集。
    2. 否则,加入可连接范围。
    3. 用连接范围替换可连接范围。
    4. 重复从 2 开始的连接范围。
  3. 从数字范围转换

 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。将此视为练习!

问题未解决?试试本站强大的搜索功能,搜索: 比较 IP 范围的列表并将其缩短为 uniq 范围
如何加载 IP 范围列表以将其与 $allowedIps 脚本一起使用?

[英]How to load a list of ip ranges to use it with $allowedIps script?

对不起,我是一个新手,但我正在尝试使用我在这里找到的脚本: 如果 IP 地址获得批准,则仅允许用户访问页面 但相反,我想从 .txt 文件加载数千个 ip 范围 像这样:(我不知道正确的功能) ip_list.txt 列表: ...

使用 JavaScript 比较时间范围

[英]Use JavaScript to compare time ranges

我有一个 Date 对象形式的时间范围集合。 我需要将这些时间范围与新的时间范围进行比较,以确保我不会添加与现有时间范围重叠或重复的时间范围。 这是集合的一个例子。 在前面的示例中,日期的日期部分无关紧要。 时代如此。 如果我有一个从上午 9:30 开始的新时间范围对象,我需要能够检测到它。 ...

比较 ISO 格式的日期范围

[英]Compare date ranges in ISO format

链接到 codeSandox 我有两个日期范围,一个来自 API,另一个来自用户输入。 两者都是 ISO 格式。 日期范围从 API: 用户输入的日期范围: 我想将date range from user input的date range from API的日期范围。 我怎样才能做到这一点? 应该 ...

IP 范围集之间的不同 IP

[英]Different IPs between sets of IP ranges

我有两组多个 IP 范围。 每个 IP 范围是一对(startIP, endIP)的长(startIP, endIP) 。 所以我有两组a和b - 我希望找到在a但不在b的 IP。 或者换句话说set(ips_a) - set(ips_b) 。 我尝试蛮力检查a中的每个 IP 和b ,但是这个 ...

使用Javascript比较PDF格式的时间范围

[英]Use Javascript to compare time ranges in PDF form

我有一个PDF表单,每个月的每一天都有6个不同的时间段,我需要确保用户完成这些时间段时这些时间段不重叠。 并非所有时间段都可以完成,但必须是唯一的。 我从上一篇文章中使用了JavaScript来比较时间范围,特别是@RobG的贡献。 但是,由于我缺乏脚本知识,因此无法为我的特定应用程序编写 ...

Highcharts比较日期范围条形图

[英]Highcharts Compare Date Ranges Bar Chart

我认为这本来是很平常的事情,但是我在任何地方都找不到例子。 我想比较2个不同日期范围的3系列数据,并在条形图中将它们彼此相邻。 通过图片更容易理解: 不幸的是,我唯一想到的就是添加一个HIDDEN系列,然后在highchart之外用html编写我的图例。 请告诉我,有更好的方法可以做 ...

使用范围列表过滤数字列表

[英]Filter List of Numbers Using a List of Ranges

我有一个年龄列表和一个年龄范围列表,使用 javascript 我想过滤掉任何年龄范围内的年龄我的代码适用于单个ageRange,但是如果ageRanges 是一个数组,我该怎么做呢? 我在单个 ageRange 中使用的代码示例: 我要过滤的数据示例: 我尝试做一个 for 循环,但很难做到正确, ...

如何根据范围列表将分数映射到等级?

[英]How to map a score to a grade based on a list of ranges?

我有一个分数,我需要根据给定的范围之一作证(见下文)。 返回分数所在范围的字符串。 例如,如果分数是 0.45,那么我应该得到“差”。 有没有办法在不使用 5 个 if else(或 switch case)语句的情况下在 JavaScript 中实现它? ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM