用Ruby确定基于IP的用户网段

用Ruby确定基于IP的用户网段,ruby,arrays,string,Ruby,Arrays,String,我有一个网段列表,希望我的网站能够根据用户的IP地址识别他们连接的网段。这样我就可以在我的网站上自动选择他们的位置,而不是让他们手动选择。确定这一点的好方法是什么 到目前为止,我有以下内容 要查找客户端IP地址,请执行以下操作: local_ip = UDPSocket.open {|s| s.connect('64.233.187.99', 1); s.addr.last } 我的网段阵列: network_segments = [ {"name"=>"Site 1", "starti

我有一个网段列表,希望我的网站能够根据用户的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中删除句点,并在每个网段中循环,以查看本地ip是否>起始地址和<结束地址,但这似乎并不准确。它应该只返回一个名称,并返回所有名称

是否有更好的方法查看本地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
使用类表示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

注意,IP地址不能可靠地字典比较,即作为字符串,考虑使用:

需要“ipaddr” a1='10.1.1.1' a2='2.1.1.1' a1真的不! i1=IPAddr.newa1 i2=IPAddr.newa2 i1false正常
另外,请注意,这是一种普遍接受的最佳做法。

有些宝石可以做到这一点。我认为这是其中之一:谢谢,但似乎更倾向于寻找地理位置。我需要根据一组特定的网段IP地址确定位置。IP是静态的、内部的,由网络工程师设置。我不需要基于公共地址的位置。考虑改变你的问题的标题,它似乎暗示地理位置。标题更新,感谢在内部设置IP地址正确。地理定位器实际上是在ip地址上工作的——它获取给定的ip并确定您所在的位置,而不仅仅是一个物理地址。但是如果你自己设置的话,那就不同了。谢谢你,蒂姆。这正是我要找的!
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