【问题标题】:Search IP /24 network in dict of ISPs根据 ISP 搜索 IP /24 网络
【发布时间】:2022-01-16 20:31:30
【问题描述】:

我有一个 IP 地址,我想在第三个点之后替换它。例如 知识产权

156.13.216.251

输出:

156.13.216.0

有了这个输出,我希望能够搜索字典以匹配结果:

IPList =

[
'156.13.216.251'
'156.13.216.250'
]

字典:

 {
            "techCountry": "ISP",
            "techCity": "saint-petersburg",
            "techName": "Cahit Eyigunlu",
            "adminState": "pr.",
            "registrantPostalCode": "e16 1ah",
            "telephone": "+443333031000",
            "domain": "156.13.216.0"
}

当输出匹配时,我想将其附加到具有匹配结果的新字典中。

我曾尝试用以下内容将其拆分为前三个,但似乎将其全部拆分:

for i in IPList:
    i.split(".",3)[:3]

【问题讨论】:

    标签: python ip-address


    【解决方案1】:

    您可以使用Regular Expressions 将其拆分为第三个点 (match pattern)。

    regex = \b\d{1,3}\.\d{1,3}\.\d{1,3}\. 
    

    例子:

    如果你有 IP 地址156.13.216.251 那么,正则表达式会找到156.13.216.

    【讨论】:

      【解决方案2】:

      Python 有一个名为 ipaddress 的库。

      您可以像这样轻松使用它:

      import ipaddress
      
      ip_list = [
      '156.13.216.251',
      '156.13.216.250'
      ]
      
      isps = [
           {
              "techCountry": "ISP",
              "techCity": "saint-petersburg",
              "techName": "Cahit Eyigunlu",
              "adminState": "pr.",
              "registrantPostalCode": "e16 1ah",
              "telephone": "+443333031000",
              "domain": "156.13.216.0"
          }
      ]
      
      # First, I suggest to map the networks to ISPs, otherwise it'll be an O(n) operation
      # for every IP.
      # We add the /24 to signal a network.
      network_to_isp = {isp["domain"] + "/24": isp for isp in isps}
      
      
      ips_not_found = []
      ips_to_isps = {}
      
      for ip in ip_list:
          network = ipaddress.IPv4Network((ip, 24), strict=False)
          isp = network_to_isp.get(str(network))
          if isp is None:
              ips_not_found.append(ip)
          else:
              ips_to_isps[ip] = isp
      

      假设我们不知道网络并希望搜索,以下代码将起作用。

      请记住,每个 IPv4 最多可能进行 32 次搜索。由于我们不知道 IP 所在的网络。我们无法绕过它。

      import ipaddress
      
      ip_list = [
      '156.13.216.251',
      '156.13.216.250'
      ]
      
      isps = [
           {
              "techCountry": "ISP",
              "techCity": "saint-petersburg",
              "techName": "Cahit Eyigunlu",
              "adminState": "pr.",
              "registrantPostalCode": "e16 1ah",
              "telephone": "+443333031000",
              "domain": "156.13.216.0"
          }
      ]
      
      # First, I suggest to map the networks to ISPs, otherwise it'll be an O(n) operation
      # for every IP.
      # We assume the network is unknown.
      network_to_isp = {ipaddress.ip_address(isp["domain"]): isp for isp in isps}
      
      def iter_supernets(address, *, max_mask=None, min_mask=0):
          network = ipaddress.ip_network(address)
          return (network.supernet(new_prefix=mask)
                  for mask in range(max_mask or network.prefixlen, min_mask, -1))
      
      ips_to_isps = {}
      
      for ip in ip_list:
          for network in iter_supernets(ip):
              isp = network_to_isp.get(network.network_address)
              if isp:
                  ips_to_isps[ip] = isp
                  break
          else:
              raise RuntimeError("No ISP found for {}".format(ip))
      

      【讨论】:

      • 我喜欢这种方法。 1个问题。例如,域是 45.11.76.0 但 IP 地址是 45.11.79.9 我可以把它带回 45.11 吗?
      • @Will 问题是网络的掩码是什么。如果是/22,则45.11.79.945.11.76.0/22 内部。它不在45.11.76.0/24 里面。您的数据不包括网络掩码,因此我设置了默认 /24。根据你的数据无法判断。
      • @将添加检查所有子网的选项。
      【解决方案3】:

      假设您有一个字典列表,您可以遍历 IPListdct_list 中的字典并检查域是否匹配。

      out = [dom for dom in IPList for dct in dct_list if '.'.join(dom.split('.')[:3]) in dct['domain']]
      

      【讨论】:

        【解决方案4】:

        你也可以使用字符串内置方法

        ip[0: ip.rfind('.')] + ".123"
        

        rfind 方法从字符串末尾找到出现的字符并提供它的索引

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-06-27
          • 1970-01-01
          • 2016-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 2017-07-23
          相关资源
          最近更新 更多