问题描述
我想做两件事:将IP地址输入转换为CIDR
以下是一些示例输入:
I want to do two things: Convert IP Address inputs into CIDRHere are some example inputs:
1.1.1.1
192.168.*.* #=> 192.168.0-255.0-255
192.168.1.2-20
1.1.1-10.1-100
检查给定的IP地址是否属于任何CIDR。这必须是一个非常快速的查询,因为它是我的Web应用程序中非常常见的查找。我想做这样的事情:
Check if a given IP Address falls into any CIDR. This must be a very fast query, as it's a very common lookup in my web app. I'm thinking of doing something like this:
def matches?(request)
valid = @ips.select {|cidr| cidr.contains?(request.remote_ip) }
!valid.empty?
end
我认为将IP范围转换为CIDR会让查询比我们的更快现在重做,这就是把IP分成整数八位字节。然后,我们将前两组八位字节编入索引以部分匹配IP。另一个选择可能是将所有内容转换为int并以这种方式进行比较。我会转换为类似 IPAddr.new(1.1.1.1)。to_i
的整数但是我需要为每个存储一个上下IP范围而不仅仅是一个CIDR。
I think converting IP ranges into CIDR will let lookups be faster than what we're doing now, which is breaking the IP's into integer octets. We then index the first two sets of octets to partially match against IP's. Another option might be converting everything to ints and doing comparisons that way. I'd convert to ints with something like this IPAddr.new("1.1.1.1").to_i
but then I'd need to store an upper and lower IP for each range instead of just a single CIDR.
如果我忽视任何主流方法,流行宝石或回购,请告诉我。谢谢!
Please let me know if I am overlooking any mainstream approaches, popular gems or repo's. Thanks!
推荐答案
那么,要获得范围的CIDR表示法,您需要一个IP和网络位数(计算得出)来自网络掩码)。
Well, to get the CIDR notation of a range, you need an IP and the number of network bits (calculated from the netmask).
要枚举给定范围的地址,您可以使用 NetAddr
(< 2.x)gem。
To enumerate the addresses of a given range, you can use the NetAddr
(< 2.x) gem.
p NetAddr::CIDR.create('192.168.1.0/24').enumerate
=> ['192.168.1.0', '192.168.1.1', '192.168.1.2'... '192.168.1.255']
您还可以动态计算网络掩码中的位数:
You can also calculate the bits from the netmask on the fly:
mask_int = NetAddr.netmask_to_i('255.255.255.0')
p NetAddr.mask_to_bits(mask_int)
=> 24
并创建基于两个IP的范围:
And to create a range based on two IPs:
lower = NetAddr::CIDR.create('192.168.1.1')
upper = NetAddr::CIDR.create('192.168.1.10')
p NetAddr.range(lower, upper)
=> ['192.168.1.2', '192.168.1.3'... '192.168.1.9']
现在你可以创建一个CIDR范围,你可以查看IP是否属于它的一部分:
So now that you can create a CIDR range, you can check to see if an IP is a part of it:
cidr = NetAddr::CIDR.create('192.168.1.0/24')
p cidr.contains?('192.168.1.10')
=> true
这篇关于Ruby / Rails中的IP范围到CIDR?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!