2010-09-03 19 views
25

kiedy to zrobićJak mogę sprawdzić, czy wartość w ciąg jest adresem IP

ip = request.env["REMOTE_ADDR"] 

uzyskać adres IP klienta jest to. Ale co jeśli chcę sprawdzić, czy wartość w zmiennej jest rzeczywiście adresem IP? Jak to zrobić?

Proszę o pomoc. Z góry dzięki. I przepraszam, jeśli to pytanie jest powtarzane, że nie podejmują wysiłek znalezienia go ...

EDIT

Co o IPv6 adresy IP ??

+2

następnym razem lepiej trochę wysiłku na znalezienie istniejącego. Oto dwa http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address i http://stackoverflow.com/questions/2999282/regular-expression-to-match -ip-address-wildcard – ankitjaininfo

Odpowiedz

30

Dlaczego nie pozwolić, aby potwierdził to za Ciebie? Nie powinieneś wprowadzać złożonych wyrażeń regularnych, których nie można utrzymać.

% gem install ipaddress 

Następnie w aplikacji

require "ipaddress" 

IPAddress.valid? "192.128.0.12" 
#=> true 

IPAddress.valid? "192.128.0.260" 
#=> false 

# Validate IPv6 addresses without additional work. 
IPAddress.valid? "ff02::1" 
#=> true 

IPAddress.valid? "ff02::ff::1" 
#=> false 

Można również użyć Ruby wbudowanej IPAddr klasy, ale nie nadaje się bardzo dobrze do walidacji.

Oczywiście, jeśli adres IP jest dostarczany przez serwer aplikacji lub platformę aplikacji, nie ma żadnego powodu do sprawdzania w ogóle. Po prostu skorzystaj z podanych informacji i z wdziękiem obsłuż wyjątki.

0

Adres IP w postaci ciągu musi zawierać dokładnie cztery liczby oddzielone kropkami. Każda liczba musi zawierać się w zakresie od 0 do 255 włącznie.

+0

Pamiętaj również, że musisz sprawdzić lokalną sieć ips i inne zastrzeżone adresy IP, takie jak 192.168.xx i 127.0.0.1 – corroded

+0

, dlaczego? faktycznie możesz uzyskać dostęp do własnej witryny z własnej sieci :) (lub nawet z rysikiem na localhost). – squadette

0

Testuj za pomocą wyrażenia regularnego:

\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} 
+2

999.999.999.999 nie jest prawidłowym adresem IP – Mischa

+0

ooh dla tego rygorystycznego sprawdzenia użyj tego, o którym tutaj mowa: http://www.regular-expressions.info/regexbuddy/ipaccurate.html – ankitjaininfo

+0

Dzięki za link .. ciekawe – Mischa

1

To wyrażenie regularne używam który znalazłem here

/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/

4

Wszystkie powyższe odpowiedzi asume IPv4 ... trzeba zadać sobie pytanie, jak to jest mądry aby ograniczyć twoją aplikację do IPv4, dodając tego rodzaju kontrole w dniu migracji sieci do IPv6.

Jeśli pytasz mnie: Nie potwierdzaj go w ogóle. Zamiast tego wystarczy przekazać ciąg znaków do postaci składników sieci, które będą używać adresu IP i pozwolić im na sprawdzenie. Złap wyjątki, które rzucają, gdy jest źle, i wykorzystaj te informacje, aby poinformować użytkownika, co się stało. Nie wynajduj ponownie koła, zbuduj na pracy innych.

+0

btw, to, co dostajesz w 'request.env ['REMOTE_ADDR']' zawsze będzie prawidłowym adresem IP, chyba że web-serwer zepsuje to! Nie ma potrzeby sprawdzania – ankitjaininfo

+0

To jest najlepsza rada. Programiści mają obsesję na punkcie walidacji składniowej, ale nie powinni: przekazywać jej programom, które będą z niej korzystać ... i zatwierdzać. – bortzmeyer

13
require 'ipaddr' 
!(IPAddr.new(str) rescue nil).nil? 

Używam go do szybkiego sprawdzenia, ponieważ używa wbudowanej biblioteki. Obsługuje zarówno ipv4, jak i ipv6. Nie jest to jednak zbyt rygorystyczne, na przykład "999.999.999.999" jest ważne. Zobacz zwycięską odpowiedź, jeśli potrzebujesz więcej precyzji.

+0

'!! IPAddr.new (str) ratowanie false' byłoby lepszym kodem –

+0

Rewizja co najmniej bieżącej biblioteki (Ruby 2.4.2) poprawnie sprawdza poprawność adresów tylko wtedy, gdy wszystkie grupy cyfr znajdują się w dopuszczalnych zakresach (od 0 do 255 dla IPv4). 'IPAddr.new '999.999.999.999'' =>' IPAddr :: InvalidAddressError: invalid address' – MatzFan

4

Użyj http://www.ruby-doc.org/stdlib-1.9.3/libdoc/ipaddr/rdoc/IPAddr.html, aby wykonać walidację dla Ciebie. Po prostu uratuj wyjątek za pomocą false i wiesz, że był on nieważny.

1.9.3p194 :002 > IPAddr.new('1.2.3.4') 
=> #<IPAddr: IPv4:1.2.3.4/255.255.255.255> 
1.9.3p194 :003 > IPAddr.new('1.2.3.a') 
ArgumentError: invalid address 
    from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' 
    from /usr/local/rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/ipaddr.rb:493:in `initialize' 
    from (irb):3:in `new' 
    from (irb):3 
    from /usr/local/rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 
27

Ruby ma już potrzebny Regex w standardowej bibliotece. Zamówienie resolv.

require "resolv" 

"192.168.1.1" =~ Resolv::IPv4::Regex ? true : false #=> true 
"192.168.1.500" =~ Resolv::IPv4::Regex ? true : false #=> false 

"ff02::1" =~ Resolv::IPv6::Regex ? true : false #=> true 
"ff02::1::1" =~ Resolv::IPv6::Regex ? true : false #=> false 

Jeśli podoba krótką drogę ...

require "resolv" 

!!("192.168.1.1" =~ Resolv::IPv4::Regex) #=> true 
!!("192.168.1.500" =~ Resolv::IPv4::Regex) #=> false 

!!("ff02::1" =~ Resolv::IPv6::Regex) #=> true 
!!("ff02::1::1" =~ Resolv::IPv6::Regex) #=> false 

Miłej zabawy!

+0

Dla Railsów zajrzyj tutaj: http: // stackoverflow.com/questions/3756184/rails-3-validate-ip-string – wingfire

+0

Aby uprościć rzeczy, '((ip_string = ~ Resolv :: IPv4 :: Regex) || (ip_string = ~ Resolv :: IPv6 :: Regex)) ? true: false' – gitb

+3

Uprość to dalej '!! ((ip_string = ~ Resolv :: IPv4 :: Regex) || (ip_string = ~ Resolv :: IPv6 :: Regex))' – jesal

0

na mecz prawidłowy adres IP z wykorzystaniem wyrażeń regularnych

^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$ 

zamiast

^([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])(\.([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])){3}$ 

ponieważ wiele regex meczu silnika pierwszej możliwości w lub sekwencja

Wypróbuj regex silnik: 10.48.0.200

testuj różnicę here

3
require 'ipaddr' 

def is_ip?(ip) 
    !!IPAddr.new(ip) rescue false 
end 

is_ip?("192.168.0.1") 
=> true 

is_ip?("www.google.com") 
=> false 

Lub, jeśli nie przeszkadza rozszerzenie klas podstawowych:

require 'ipaddr' 

class String 
    def is_ip? 
    !!IPAddr.new(self) rescue false 
    end 
end 

"192.168.0.1".is_ip? 
=> true 

"192.168.0.512".is_ip? 
=> false 
7

Ponieważ większość odpowiedzi nie mówią o walidacji IPv6, miałem podobny problem. Rozwiązałem go przy użyciu Biblioteki Regi Regex, tak jak wspomniał @wingfire.

Ale użyłem również Bibliotekę REGEXP używać to union sposób jak wyjaśniono here

ja tak mam ten kod do sprawdzania poprawności:

validates :ip, :format => { 
        :with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex) 
       } 

Nadzieja to może komuś pomóc!

1

Spróbuj

Zastosowanie IPAddr

require 'ipaddr' 
true if IPAddr.new(ip) rescue false 
Powiązane problemy