私は ip-address gem を使用してきましたが、フォームのネットマスクから変換する機能がないようです
255.255.255.0
CIDR フォームに
/24
前者を後者にすばやく変換する方法を知っている人はいますか?
これが手っ取り早く汚れた方法です
require 'ipaddr'
puts IPAddr.new("255.255.255.0").to_i.to_s(2).count("1")
そのための適切な関数があるはずですが、それを見つけることができなかったので、「1」を数えるだけです
この関数をさまざまな場所で使用し、モンキーパッチを気にしない場合は、次の方法が役立ちます。
IPAddr.class_eval
def to_cidr
"/" + self.to_i.to_s(2).count("1")
end
end
それからあなたは得る
IPAddr.new('255.255.255.0').to_cidr
# => "/24"
参考までに、検索しているユーザーが情報に簡単にアクセスできるようにします...
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"
これは、より数学的なアプローチであり、文字列を絶対に避けます。
def cidr_mask
Integer(32-Math.log2((IPAddr.new(mask,Socket::AF_INET).to_i^0xffffffff)+1))
end
「マスク」は 255.255.255.0 のような文字列です。「マスク」がすでに IP アドレスの整数表現である場合は、それを変更して、最初の引数を「マスク」だけに変更できます。
たとえば、マスクが「255.255.255.0」の場合、IPAddr.new(mask,Socket::AF_INET).to_i は 0xffffff00 になり、0xffffffff と xor 演算されて 255 になります。
これに 1 を加えて 256 ホストの完全な範囲にし、256 の 2 を底とする対数を求めます。これは 8 (ホスト アドレスに使用されるビット) に等しく、32 からその 8 を引いて 24 (ビット) に等しくなります。ネットワークアドレスに使用されます)。
次に、Math.log2 が float を返すため、integer にキャストします。
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
編集: NathanOliver の要求に応じて、実装に説明を追加しました