に私は、IPアドレスの宝石を使用してきたし、CIDR形式ネットマスクはCIDRにルビー
にフォーム255.255.255.0
のネットマスクから変換する能力を持っていないようです
/24
誰もが前者を後者にすばやく変換する方法を知っていますか?ここで
に私は、IPアドレスの宝石を使用してきたし、CIDR形式ネットマスクはCIDRにルビー
にフォーム255.255.255.0
のネットマスクから変換する能力を持っていないようです
/24
誰もが前者を後者にすばやく変換する方法を知っていますか?ここで
があり、私はそれを見つけることができなかった、そのための適切な関数であるので、あなたはするつもりなら、私はちょうど「1」
をカウントする必要があり、迅速かつ汚い方法
require 'ipaddr'
puts IPAddr.new("255.255.255.0").to_i.to_s(2).count("1")
です多くの場所で関数を使用しているとmonkeypatchingを気にしない、これは助けることができる:
IPAddr.class_eval
def to_cidr
"/" + self.to_i.to_s(2).count("1")
end
end
を次にあなたが得る
ただ、FYIとして3210IPAddr.new('255.255.255.0').to_cidr
# => "/24"
カウント( "1")を使うよりも何かが適切であるかどうかはわかりません。おそらくこのような何か? '32 - (2 ** 32 - 1 - IPAddr.new(" 255.255.255.0 ")。to_i).to_s(2)。長さ ' –
Cで、私はおそらく右へのシフトを行い、&1で到達可能性があるまで、例えば 'bits = 32; unsigned int ipaddr = 0xFFFFFF00; while(ipaddr&1 == 0){ipaddr = ipaddr> > 1; bits - ;} '上記の場合、8回右にシフトする必要があると思います。 – YOU
、そして...検索している人のために簡単にアクセス
を情報を維持するためには、ここではCIDRからネットマスク形式に変換するための簡単な方法です。例えば
def cidr_to_netmask(cidr)
IPAddr.new('255.255.255.255').mask(cidr).to_s
end
:
cidr_to_netmask(24) #=> "255.255.255.0"
cidr_to_netmask(32) #=> "255.255.255.255"
cidr_to_netmask(16) #=> "255.255.0.0"
cidr_to_netmask(22) #=> "255.255.252.0"
あなたは、IPアドレスの宝石を使用する必要がない場合、あなたはnetaddr宝石
でこれを行うことができますrequire 'netaddr'
def to_cidr_mask(dotted_mask)
NetAddr::CIDR.create('0.0.0.0/'+dotted_mask).netmask
end
to_cidr_mask("255.224.0.0") # => "/11"
は、ここですべてのコストでの文字列を避け、より数学的なアプローチだ:「マスク」255.255.255.0のような文字列であることと
def cidr_mask
Integer(32-Math.log2((IPAddr.new(mask,Socket::AF_INET).to_i^0xffffffff)+1))
end
。 "mask"がすでにIPアドレスの整数表現であれば、それを修正し、最初の引数を単に "mask"に変更することができます。
ので、マスクが "255.255.255.0"、IPAddr.new(マスク、ソケット:: AF_INET)だった場合、たとえば、.to_iは255
に等しく、その後は0xffffffffとのXORをとる0xffffff00、なりますこれを1に加えて、256のホストの完全な範囲にしてから、ログベース2を256(ホストアドレスに使用されるビット)に等しい8を求め、その32を32から減算します。ネットワークアドレスに使用されるビット)。
Math.log2がfloatを返すため、整数にキャストします。
間に合わせ変換:
"255.255.255.0".split(".").map { |e| e.to_i.to_s(2).rjust(8, "0") }.join.count("1").split(".")
=> Iは、アレイ内の各要素の配列
.map { |e| e.to_i.to_s(2).rjust(8, "0") }
=>マスクを分割:
.to_i
=>整数に変換し
.to_s(2)
=>
.rjust(8, "0")
=>パディングを追加
=>地図
同じカーディナリティ持つ配列を返す二 に整数に変換.join
=>完全な文字列に配列を変換し
.count("1")
=> "1" の文字をカウント=> CIDRは
def mask_2_ciddr mask
"/" + mask.split(".").map { |e| e.to_i.to_s(2).rjust(8, "0") }.join.count("1").to_s
end
mask_2_ciddr "255.255.255.0"
=> "/24"
mask_2_ciddr "255.255.255.128"
=> "/25"
require 'ipaddr'
def serialize_ipaddr(address)
mask = address.instance_variable_get(:@mask_addr).to_s(2).count('1')
"#{address}/#{mask}"
end
serialize_ipaddr(IPAddr.new('192.168.0.1/24')) # => "192.168.0.0/24"
をマスク付けコードは、プライベートアクセスすることにより、マスキングを実現しますIPAddrインスタンス(アドレス、serialize_ipaddrに渡される)のインスタンス変数* @ mask_addr)。インスタンス変数は、クラスのパブリックAPIの一部ではありませんが、ここで、それは私の意見で#inspectから文字列を解析よりはましだとこれは(方法は推奨されません
を次のようにプロセスは次のとおりです。
255.255.255.0 -> 4294967040 -> 11111111111111111111111100000000
をマスクEDIT:追加されましたNathanOliver
によって要求された実装への説明このコードスニペットは問題を解決するかもしれませんが、[説明を含む](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)は、あなたの質を改善するのに本当に役立ちます役職。将来読者の質問に答えていることを覚えていて、コード提案の理由を知らない人もいるかもしれません。 – NathanOliver
一つの解決策は、より完全に見えている代わりにipadminの宝石を使用することが考えられます。 私はまだコードの観点からこれに対する解決策が何であるか見ることに興味があります。 –