wenn ich das tue
ip = request.env["REMOTE_ADDR"]
Ich bekomme die IP Adresse des Kunden drauf. Aber was ist, wenn ich überprüfen möchte, ob der Wert in der Variablen wirklich eine IP ist? Wie mache ich das?
Bitte helfen Sie. Danke im Voraus. Und falls sich diese Frage wiederholt, habe ich mir nicht die Mühe gemacht, sie zu finden ...
EDIT
Was ist mit IPv6-IPs?
Warum lassen Sie eine Bibliothek es nicht für Sie validieren? Sie sollten keine komplexen regulären Ausdrücke einführen, die nicht zu pflegen sind.
% gem install ipaddress
Dann in Ihrer Anwendung
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
IPAddress.valid_ipv4? "192.128.0.12"
#=> true
IPAddress.valid_ipv6? "192.128.0.12"
#=> false
Sie können auch die in Ruby integrierte Klasse IPAddr
verwenden, diese eignet sich jedoch nicht sehr gut zur Validierung.
Wenn Ihnen die IP-Adresse vom Anwendungsserver oder Framework zur Verfügung gestellt wird, besteht natürlich kein Grund zur Überprüfung. Verwenden Sie einfach die Informationen, die Ihnen zur Verfügung gestellt werden, und behandeln Sie alle Ausnahmen ordnungsgemäß.
Ruby hat bereits den benötigten Regex in der Standardbibliothek. Kasse auflösen .
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
Wenn es Ihnen auf kurzem Weg gefällt ...
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
Habe Spaß!
Update (08.10.2018):
Von den Kommentaren unten liebe ich die sehr kurze Version:
!!(ip_string =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex]))
Sehr elegant mit Rails (auch eine Antwort von unten):
validates :ip,
:format => {
:with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
}
require 'ipaddr'
!(IPAddr.new(str) rescue nil).nil?
Ich benutze es für eine schnelle Überprüfung, da es eine eingebaute Bibliothek verwendet. Unterstützt sowohl ipv4 als auch ipv6. Es ist nicht sehr streng, es heißt zum Beispiel, dass '999.999.999.999' gültig ist. Sehen Sie die Gewinnerantwort, wenn Sie mehr Präzision benötigen.
Da die meisten Antworten nicht über die IPV6-Validierung sprechen, hatte ich ein ähnliches Problem. Ich habe es mit der Ruby Regex Library gelöst, wie @wingfire es erwähnt hat.
Aber ich habe auch die Regexp-Bibliothek verwendet, um die union
-Methode zu verwenden, wie erklärt hier
Ich habe also diesen Code für eine Validierung:
validates :ip, :format => {
:with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
}
Hoffe das kann jemandem helfen!
Bei allen obigen Antworten wird von IPv4 ausgegangen ... Sie müssen sich fragen, wie sinnvoll es ist, Ihre App auf IPv4 zu beschränken, indem Sie diese Art von Überprüfungen an diesem Tag der Migration des Netzes auf IPv6 hinzufügen.
Wenn Sie mich fragen: Validieren Sie es überhaupt nicht. Übergeben Sie die Zeichenfolge stattdessen so wie sie ist an die Netzwerkkomponenten, die die IP-Adresse verwenden, und lassen Sie sie die Validierung durchführen. Fangen Sie die Ausnahmen ab, die sie auslösen, wenn sie falsch sind, und teilen Sie dem Benutzer anhand dieser Informationen mit, was passiert ist. Erfinden Sie das Rad nicht neu, bauen Sie auf der Arbeit anderer auf.
Verwenden Sie http://www.Ruby-doc.org/stdlib-1.9.3/libdoc/ipaddr/rdoc/IPAddr.html , um die Validierung für Sie durchzuführen. Retten Sie die Ausnahme einfach mit false und Sie wissen, dass sie ungültig war.
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>'
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
Oder wenn es Ihnen nichts ausmacht, die Kernklassen zu erweitern:
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
Diesen regulären Ausdruck verwende ich, den ich gefunden habe hier
/^(?:(?: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]?)$/
zum Abgleichen eine gültige IP-Adresse mit Regexp verwenden
^(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}$
anstatt
^([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}$
weil viele reguläre Ausdrücke mit der ersten Möglichkeit in der OR Sequenz übereinstimmen
sie können Ihre Regex-Engine ausprobieren: 10.48.0.200
testen Sie den Unterschied hier
Die IP-Adresse in Form einer Zeichenfolge muss genau vier durch Punkte getrennte Zahlen enthalten. Jede Zahl muss im Bereich von 0 bis einschließlich 255 liegen.
Bestätigen Sie mit dem regulären Ausdruck:
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}