私がこれをするとき
ip = request.env["REMOTE_ADDR"]
クライアントのIPアドレスを取得します。しかし、変数の値が本当にIPであるかどうかを検証したい場合はどうなりますか?それ、どうやったら出来るの?
助けてください。前もって感謝します。そして、この質問が繰り返されてすみません、私はそれを見つける努力をしませんでした...
[〜#〜]編集[〜#〜]
IPv6 IPについてはどうですか?
ライブラリ 検証させてみませんか?維持することが不可能な複雑な正規表現を導入するべきではありません。
% gem install ipaddress
次に、アプリケーションで
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
Rubyの組み込みのIPAddr
クラスを使用することもできますが、検証にはあまり適していません。
もちろん、IPアドレスがアプリケーションサーバーまたはフレームワークから提供されている場合は、検証する理由はまったくありません。提供された情報を使用するだけで、例外を適切に処理できます。
Rubyには、標準ライブラリに必要な正規表現がすでに含まれています。チェックアウト 解決 。
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
あなたがそれを短い方法で好きなら...
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
楽しんで!
更新(2018-10-08):
以下のコメントから、私は非常に短いバージョンが大好きです:
!!(ip_string =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex]))
Rails(以下からの回答も))で非常にエレガント:
validates :ip,
:format => {
:with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
}
require 'ipaddr'
!(IPAddr.new(str) rescue nil).nil?
内蔵ライブラリを使用しているので、クイックチェックに使用しています。 ipv4とipv6の両方をサポートします。それほど厳密ではありませんが、たとえば「999.999.999.999」が有効であると書かれています。より正確な情報が必要な場合は、勝利の答えをご覧ください。
ほとんどの回答はIPV6検証について語っていないので、同様の問題がありました。 @wingfireが言及したように、Ruby Regex Libraryを使用して解決しました。
しかし、説明したように、正規表現ライブラリを使用してunion
メソッドも使用しました ここ
私は検証のためにこのコードを持っています:
validates :ip, :format => {
:with => Regexp.union(Resolv::IPv4::Regex, Resolv::IPv6::Regex)
}
これが誰かを助けることができることを願っています!
http://www.Ruby-doc.org/stdlib-1.9.3/libdoc/ipaddr/rdoc/IPAddr.html を使用すると、検証が行われます。例外をfalseで救出すると、例外が無効であることがわかります。
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>'
上記のすべての回答はIPv4を想定しています... IPv6に移行するネットの今日にこの種のチェックを追加して、アプリをIPv4に制限することがどれほど賢明かを自問する必要があります。
あなたが私に尋ねた場合:それをまったく検証しないでください。代わりに、IPアドレスを使用するネットワークコンポーネントに文字列をそのまま渡して、検証を行わせます。間違っている場合にスローされる例外をキャッチし、その情報を使用してユーザーに何が起こったかを伝えます。車輪を再発明するのではなく、他の人の仕事に基づいて構築してください。
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
または、コアクラスを拡張してもかまわない場合:
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
私が見つけたこの正規表現 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]?)$/
正規表現を使用して有効なIPアドレスと一致させるため
^(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}$
の代わりに
^([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}$
多くの正規表現エンジンがORシーケンスの最初の可能性に一致するため
あなたはあなたの正規表現エンジンを試すことができます:10.48.0.200
違いをテストする ここ
文字列形式のIPアドレスには、ドットで区切られた正確に4つの数字が含まれている必要があります。各数値は、0以上255以下の範囲内でなければなりません。
正規表現を使用して検証します。
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}