You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中提取IP地址范围子集以规避内存溢出问题

嘿,我之前处理大规模IP扫描任务时也碰到过一模一样的内存溢出问题,给你个针对性的解决方案:

解决大IP段内存不足问题:提取32个地址子集

核心问题在于处理10.234.xxx.1/24这类/24段时,直接把整个IP范围转成数组会生成256个元素,当有大量这类段时很容易撑爆内存。我们可以均匀抽取32个IP来替代全量数组,既保持样本代表性,又大幅降低内存占用。

修改后的代码片段

ips.each do |ip|
  ip_from = if ip.instance_of?(Nexpose::HostName)
              ip.host
            else
              # 处理IP范围:不再全量转换,而是抽取32个样本
              ip_range = ip.from..ip.to
              total_ips = ip_range.size
              # 如果IP总数<=32,直接取全部;否则按间隔抽取32个
              if total_ips <= 32
                ip_range.map(&:to_s)
              else
                step = total_ips / 32
                # 从范围中按步长取元素,确保覆盖整个段
                (0..31).map { |i| ip_range.begin + (i * step) }.map(&:to_s)
              end
            end

  # 后续你的处理逻辑:ip_from2 = ip_from.select{ |i|... }
end

关键逻辑解释

  • 适配小范围场景:先计算当前IP段的总数量,如果本身就小于等于32个,直接保留全量,避免抽样丢失数据。
  • 均匀覆盖抽样:当IP总数大于32时,计算步长(总数量/32),从起始IP开始每步长取一个IP,这样能均匀覆盖整个/24段,不会集中在某一小片区域,适合扫描、检测这类需要代表性样本的场景。
  • 从根源减少内存占用:直接通过计算偏移量获取目标IP,而不是先把整个范围转成数组,彻底避免全量数组带来的内存开销。

可选优化:随机抽样

如果你的场景需要随机样本,也可以用随机抽取32个唯一IP的方式,代码如下:

else
  ip_range = ip.from..ip.to
  total_ips = ip_range.size
  if total_ips <= 32
    ip_range.map(&:to_s)
  else
    # 生成32个不重复的随机索引,对应到IP范围
    random_indices = (0...total_ips).to_a.sample(32).sort
    random_indices.map { |idx| ip_range.begin + idx }.map(&:to_s)
  end
end

内容的提问来源于stack exchange,提问作者Derek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:47:37