【问题标题】:determine network segment of user based on IP with Ruby使用Ruby根据IP确定用户的网段
【发布时间】:2015-03-19 23:32:40
【问题描述】:

我有一个网段列表,并希望我的网站能够根据用户的 IP 地址识别用户连接到的网段。这样我就可以在我的网站上自动选择他们的位置,而他们必须手动选择。有什么好的方法或确定这一点?

到目前为止,我有以下内容。

要查找客户端 IP 地址:

local_ip = UDPSocket.open {|s| s.connect('64.233.187.99', 1); s.addr.last }

我的网络段数组:

network_segments = [
{"name"=>"Site 1", "starting_address"=>"192.168.168.1", "ending_address"=>"192.168.175.254"},
{"name"=>"Site 2", "starting_address"=>"192.168.184.1", "ending_address"=>"192.168.191.254"},
{"name"=>"Site 3", "starting_address"=>"192.168.176.1", "ending_address"=>"192.168.183.254"}
]

我尝试从 IP 中删除句点并遍历每个网段以查看 local_ip 是否 > starting_address ending_address,但这似乎并不准确。它应该只返回一个名称,并返回所有名称。

有没有更好的方法来查看 local_ip 是否在我的任何网段 IP 之间?

ip = local_ip.delete('.').to_i

network_segments.each do |seg|
   start_addr = seg['starting_address'].delete('.').to_i
   end_addr = seg['ending_address'].delete('.').to_i

    if ip > start_addr and ip < end_addr
      puts seg['name']
    end
end

【问题讨论】:

  • 有些宝石可以做到这一点。我认为这是其中之一:github.com/alexreisner/geocoder
  • 谢谢,但似乎更适合寻找地理位置。我需要根据一组特定的网段 IP 地址确定位置。 IP 是静态的、内部的,由网络工程师设置。我不需要基于公共地址的位置。
  • 考虑更改问题的标题,它似乎暗示了地理位置。
  • 标题已更新,谢谢
  • 啊内部正确设置IP地址。地理定位器确实在 ip-address 上工作 - 它采用给定的 IP 并确定您所在的位置(不仅仅是物理地址)。但如果你自己设置它们,那就是另一个问题了。

标签: ruby arrays string


【解决方案1】:

使用IPAddr 类(表示IP 地址)而不是删除点的字符串。 IPAddr 提供比较运算符,可以了解哪些地址大于/小于另一个。

require 'ipaddr'
# ...
local_ip = IPAddr.new(local_ip)
network_segments.each do |seg|
  if local_ip > IPAddr.new(seg['starting_address']) and local_ip < IPAddr.new(seg['ending_address'])
    puts seg['name']
  end
end

编辑:除了您的范围从 1..254 而不是 0..255 的事实之外,您还可以使用网络掩码范围实施检查,例如:

IPAddr.new("192.168.168.1/21").to_range.first.to_s       # => "192.168.168.0"
IPAddr.new("192.168.168.1/21").to_range.last.to_s       # => "192.168.175.255"
IPAddr.new("192.168.168.1/21").include?("192.168.170.1") # => true
IPAddr.new("192.168.168.1/21").include?("192.168.176.1") # => false

【讨论】:

  • 谢谢你,蒂姆。这正是我想要的!
【解决方案2】:

请注意,IP 地址在字典上不能可靠地进行比较(即作为字符串),请考虑使用 standard IPAddr module

require 'ipaddr'

a1 = '10.1.1.1'
a2 = '2.1.1.1'
a1 < a2 # => true (nope!)

i1 = IPAddr.new(a1)
i2 = IPAddr.new(a2)
i1 < i2 # => false (ok)

另外,请注意,use &amp;&amp; instead of and for boolean logic 是公认的最佳做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2016-08-24
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2011-07-04
    相关资源
    最近更新 更多