Как вы можете определить, находится ли ip, скажем, 62.156.244.13
в пределах 62.0.0.0
и 62.255.255.255
Узнайте, находится ли IP в пределах диапазона IP-адресов
Ответ 1
>> require "ipaddr"
=> true
>> low = IPAddr.new("62.0.0.0").to_i
=> 1040187392
>> high = IPAddr.new("62.255.255.255").to_i
=> 1056964607
>> ip = IPAddr.new("62.156.244.13").to_i
=> 1050473485
>> (low..high)===ip
=> true
Если вам предоставляется сеть вместо начального и конечного адресов, она еще проще
>> net = IPAddr.new("62.0.0.0/8")
=> #<IPAddr: IPv4:62.0.0.0/255.0.0.0>
>> net===IPAddr.new("62.156.244.13")
=> true
IPAddr
также будет работать с адресами IPv6
>> low = IPAddr.new('1::')
=> #<IPAddr: IPv6:0001:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
>> high = IPAddr.new('2::')
=> #<IPAddr: IPv6:0002:0000:0000:0000:0000:0000:0000:0000/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>
>> (low..high)===IPAddr.new('1::1')
=> true
Ответ 2
Я бы использовал эту маленькую убойную функцию, чтобы преобразовать IP-адреса в целые числа, а затем сравнить их.
def ip_addr_in_range?(low, high, addr)
int_addr = numeric_ip(addr)
int_addr <= numeric_ip(high) && int_addr >= numeric_ip(low)
end
def numeric_ip(ip_str)
ip_str.split('.').inject(0) { |ip_num, part| ( ip_num << 8 ) + part.to_i }
end
def test_ip_addr_in_range(low, high, addr, expected)
result = ip_addr_in_range?(low, high, addr)
puts "#{addr} #{(expected ? 'should' : 'should not')} be within #{low} and #{high}: #{(expected == result ? 'PASS' : 'FAIL')}"
end
test_ip_addr_in_range("192.168.0.0", "192.168.0.255", "192.168.0.200", true)
test_ip_addr_in_range("192.168.0.0", "192.168.0.155", "192.168.0.200", false)
test_ip_addr_in_range("192.168.0.0", "192.168.255.255", "192.168.100.200", true)
test_ip_addr_in_range("192.168.0.0", "192.168.100.255", "192.168.150.200", false)
test_ip_addr_in_range("192.168.255.255", "192.255.255.255", "192.200.100.100", true)
test_ip_addr_in_range("192.168.255.255", "192.255.255.255", "192.100.100.100", false)
test_ip_addr_in_range("192.168.255.255", "255.255.255.255", "200.200.100.100", true)
test_ip_addr_in_range("192.168.255.255", "255.255.255.255", "180.100.100.100", false)
$ ruby ip_range.rb
192.168.0.200 should be within 192.168.0.0 and 192.168.0.255: PASS
192.168.0.200 should not be within 192.168.0.0 and 192.168.0.155: PASS
192.168.100.200 should be within 192.168.0.0 and 192.168.255.255: PASS
192.168.150.200 should not be within 192.168.0.0 and 192.168.100.255: PASS
192.200.100.100 should be within 192.168.255.255 and 192.255.255.255: PASS
192.100.100.100 should not be within 192.168.255.255 and 192.255.255.255: PASS
200.200.100.100 should be within 192.168.255.255 and 255.255.255.255: PASS
180.100.100.100 should not be within 192.168.255.255 and 255.255.255.255: PASS
Ответ 3
Вдохновленный jdls ответом, но с диапазоном:
class String
def to_ip
split(".").inject(0) { |s, p| (s << 8) + p.to_i }
end
end
("62.0.0.0".to_ip.."62.255.255.255".to_ip).include?("62.156.244.13".to_ip)
Ответ 4
Есть метод #include?
И вы можете сделать только:
IPAddr.new("127.0.0.1/8").include? "127.1.10.200"
Ответ 5
Я предпочитаю этот подход для преобразования IP-адреса в целое число для сравнения диапазона:
# n_ip("192.1.1.23") will return the number 192001001023
def n_ip(input)
input.split(".").collect{|p| p.rjust(3, "0")}.join.to_i
end
def ip_in_range?(from, to, given)
(n_ip(from)..n_ip(to).include?(n_ip(given))
end
Теперь вы можете проверить значение следующим образом:
>> ip_in_range?("192.168.0.0", "192.168.0.255","192.168.0.200")
ip_in_range?("192.168.0.0", "192.168.0.255","192.168.0.200")
=> true
>> ip_in_range?("192.168.0.0", "192.168.0.255", "192.168.1.200")
ip_in_range?("192.168.0.0", "192.168.0.255", "192.168.1.200")
=> false
Возвращаемое целое число не является 32-разрядным представлением IP-адреса. Логика будет работать для всех допустимых IP-адресов.
Ответ 6
jdl answer - это хорошо. Я бы сделал in_range? функция однострочный:
def ip_addr_in_range?(low, high, addr)
(numeric_ip(low) .. numeric_ip(high)) === numeric_ip(addr)
end
Ответ 7
Не делайте этого сложнее, чем это должно быть.
def check_ip(ip)
'62.0.0.0' < ip and ip < '62.255.255.255'
end
check_ip '62.156.244.13' #=> true
Изменить: Или, если вы используете Rails/ActiveSupport:
def check_ip(ip)
ip.starts_with? '62'
end
check_ip '62.156.244.13' #=> true