【问题标题】:Fast file search algorithm for IP addressesIP 地址的快速文件搜索算法
【发布时间】:2011-02-09 06:34:34
【问题描述】:

问题

如果某个 IP 地址存在于包含 IP 地址的文件中,最快的方法是:

219.93.88.62
219.94.181.87
219.94.193.96
220.1.72.201
220.110.162.50
220.126.52.187
220.126.52.247

约束

  • 没有数据库(例如 MySQL、PostgreSQL、Oracle 等)
  • 允许不频繁的预处理(参见可能性部分)
  • 不必每次查询都加载文件(131Kb)会很好
  • 使用低于 5 MB 的磁盘空间
  • 没有额外的 PHP 模块

文件详情

  • 每行一个 IP 地址
  • 9500+ 行

可能的解决方案

  • 创建目录层次结构 (radix tree?),然后使用 is_dir()(遗憾的是,这使用了 87 兆字节)

【问题讨论】:

标签: php algorithm ip-address text-search


【解决方案1】:

如果在到达 232.0.17.1 之前要检查 9,000 个不匹配项,那么逐行扫描文件以查找 IP 似乎很痛苦

您的文件是否被限制为单个文件?例如假设这个列表是被禁止的 IP,而您只是想看看是否有一个“在”列表中。

如果你创建了一个包含多个文件的 DIR:

BannedIPs
  +- 0.ips
  +- 1.ips
  +- 37.ips
  +- 123.ips
  +- 253.ips
  +- 254.ips

每个文件只包含以该数字开头的 IP 地址。

如果你足够幸运,分布均匀......你将拥有 256 个文件,但每个文件只有大约 37 个条目。

因此,当您要测试时:232.0.17.1 您查看 232.ips 文件并扫描它。

【讨论】:

    【解决方案2】:

    可能不会很快,但我会尝试一下:如果 IP 地址文件没有太大变化,请将文件读入一个数组并缓存它(可能是 Memcache),然后在每个请求上从那里搜索。

    【讨论】:

      【解决方案3】:

      编辑 我没有注意到php 标记,我不知道在那种语言中是否可以使用以下类型的东西。但无论如何我都会把它留给这个想法。

      IPv4 地址可以表示为 32 位数字,因此我只需创建一个 int32 数组,使用以下 Python 式伪代码将您的地址转换为“整数”:

      x = 0
      i = 24
      s = '111.222.333.444'
      for part in s.split('.'):
          x += part.toint() << i
          i -= 8
      IPlist.append(x)
      

      然后就可以得到输入地址,用同样的方法转换成int,对数组进行二分查找。

      对于 ~10 k 行,数组将占用 ~40 kBytes。

      【讨论】:

        【解决方案4】:

        由于您的文件已经按排序顺序存储了 IP 地址,因此您可以使用二进制搜索在 O(log(n)) 时间内快速找到特定的 IP 地址。

        如果您想进一步加快速度,您可以在内存中缓存例如每 100 行并首先使用内存中的二进制搜索,然后您就知道需要读入文件的哪个部分来完成搜索。

        话虽如此,131kB真的不算多,所以最简单最快的解决方案就是购买更多的内存,并将整个文件缓存在内存中的哈希表中。

        【讨论】:

          猜你喜欢
          • 2010-11-05
          • 2021-01-24
          • 2012-04-24
          • 2019-02-02
          • 1970-01-01
          • 1970-01-01
          • 2014-11-05
          • 2014-08-20
          • 2012-03-10
          相关资源
          最近更新 更多