检查用户的IP地址是否在一系列IP地址范围内

5
在我的Python应用程序中,我有一个IP地址字符串数组,看起来像这样:
[
    "50.28.85.81-140", // Matches any IP address that matches the first 3 octets, and has its final octet somewhere between 81 and 140
    "26.83.152.12-194" // Same idea: 26.83.152.12 would match, 26.83.152.120 would match, 26.83.152.195 would not match
]

我安装了netaddr,虽然文档看起来很好,但我无法理解它。这一定非常简单——如何检查给定的IP地址是否与这些范围之一匹配?不需要特别使用netaddr——任何简单的Python解决方案都可以。

可能是重复的问题:如何在Python中检查IP是否在网络中 - MooingRawr
同样,这也是来自于相同的重复链接:https://dev59.com/8HRA5IYBdhLWcg3wzhRY#820124 - MooingRawr
文本内容翻译如下:格式不一样。 - Faibbus
2个回答

6

这个想法是将IP地址拆分,逐个组件进行检查。

mask = "26.83.152.12-192"
IP = "26.83.152.19"
def match(mask, IP):
   splitted_IP = IP.split('.')
   for index, current_range in enumerate(mask.split('.')):
      if '-' in current_range:
         mini, maxi = map(int,current_range.split('-'))
      else:
         mini = maxi = int(current_range)
      if not (mini <= int(splitted_IP[index]) <= maxi):
         return False
   return True

1
如果使用内置的 https://docs.python.org/3/library/ipaddress.html,可以这样编写代码:`if IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28'): `。 - benzkji
@benzkji ipaddress是值得一提的,尽管OP的情况不能被转换成斜线符号表示法。 - Faibbus
虽然有ipaddress.summarize_address_range,所以您只需要迭代返回的网络列表中的所有网络。https://docs.python.org/3/library/ipaddress.html#ipaddress.summarize_address_range - benzkji

3

我不确定这是最优解决方案,但这是基于Python编写的,不需要额外的软件包。

  • 解析ip_range,创建一个列表,如果是简单值则创建一个元素,如果是范围则创建一个range。因此它创建了一个包含4个整数/范围对象的列表。
  • 然后使用split版本的地址将其与zip起来,并在其他值的范围内测试每个值

注意:使用range可确保超快速的in测试(在Python 3中)(为什么 Python 3 中的 "1000000000000000 in range(1000000000000001)" 能如此之快?)

ip_range = "50.28.85.81-140"

toks = [[int(d)] if d.isdigit() else range(int(d.split("-")[0]),int(d.split("-")[1]+1)) for d in ip_range.split(".")]

print(toks) # debug

for test_ip in ("50.28.85.86","50.284.85.200","1.2.3.4"):
    print (all(int(a) in b for a,b in zip(test_ip.split("."),toks)))

结果(如预期):

[[50], [28], [85], range(81, 140)]
True
False
False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接