2

我有一组 ip 范围,我需要查找用户给定的 ip 是否存在于给定的 ip 范围列表之间。

这是这个问题的延续

如何使用节点js检查给定的ip是否在给定的ip范围之间

Jonas 帮助我获取了 ip 是否存在。但我不想进行详尽的迭代搜索,我想进行快速的性能密集型搜索,因为我的 ip 范围(或数字范围)列表会很大。

我研究了 jonas 指出的布隆过滤器,但我不相信布隆过滤器可能会有所帮助。我也在看区间树,但我不认为它可以搜索区间,它将区间作为输入。

我的 ip 列表范围https://github.com/client9/ipcat/blob/master/datacenters.csv#L4

如何快速搜索它。我正在使用节点 js

4

1 回答 1

0

我观察到您的许多 ip 看起来像这样:

123.123.123.0 - 123.123.123.255

所以要过滤掉它们,我们只需要阻止每个 ip 开头:

123.123.123

现在只剩下 16E6 个 IP 范围被阻止。但是,您可能只会阻止其中的一些,这使我们能够将其存储在 Set 中。一点代码:

const blockedRange = new Set();

function IPtoBlock(ip){
   return ip.split(".").slice(0,3).join(".");
}

//to block an ip range ( if youve got one ip of it):
blockedRange.add( IPtoBlock("192.168.2.48") );

//to check for an ip
blockedRange.has( IPtoBlock( someip ));

所以现在只有几个范围不是块,比如:

 5.44.26.144 - 5.44.26.159

但是,嘿,只有 15 个 ip,我们可以将其添加到禁止 ip 列表中:

const blockedIPs = new Set();

function NumtoIP(num){
  return (num+"").split("").reduce((res,char,i) =>
    res + (!i || i%3?"":".") + (char === "0"?"":char)
  ,"");
 }

function addRange(start,end){
 start = IPtoNum(start);
 end = IPtoNum(end);//include from last answer
 for(var i = start; i <= end; i++){
   blockedIPs.add( NumtoIP( i ) );
 }
}

因此,当迭代我们的范围列表时,我们可以分开:

ranges.forEach(([min,max]) => {
  if( min.substr(-1) === "0" && max.substr(-3) === "255" ){
      blockedRange.add( IPtoBlock( min ) );
  }else{
      addRange(min, max);
  }
});

检查 ip 是否未通过检查

function isBlocked(ip){
  return blockedIPs.has(ip) && blockedRange.has( IPtoBlock(ip) );
 }
于 2017-09-13T19:03:25.607 回答