質問

っては、ipアドレスの逸品となっているからネットマスクの形成

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

" mask" 255.255.255.0のような文字列です。変更して、最初の引数を「マスク」に変更できます。 " mask"の場合すでにIPアドレスの整数表現です。

たとえば、マスクが" 255.255.255.0"の場合、IPAddr.new(mask、Socket :: AF_INET).to_iは0xffffff00になり、その後0xffffffffと255になります。 p>

1を追加して256ホストの完全な範囲にし、次に8に等しい256の対数ベース(ホストアドレスに使用されるビット)を見つけ、32から24に等しい8を減算します(ネットワークアドレスに使用されるビット)。

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)にアクセスすることにより、マスキングを実現します。これは推奨されない方法です(インスタンス変数はクラスpublic APIの一部ではありませんが、ここでは、私の意見では #inspect の文字列を解析するよりも優れています。

したがって、プロセスは次のとおりです。

  1. ネットマスクを表すインスタンス変数 @mask_addr を取得します
  2. バイナリ表現を取得します。 255.255.255.0-> 4294967040-> 11111111111111111111111100000000
  3. CIDRマスク(24)を取得するには、基数2の1をカウントします
  4. アドレス&で構成される文字列を作成しますマスク

編集:NathanOliverの要求に応じて実装に説明を追加

ここに、IPAddr gemなしでそれを行う方法があります

(('1'*cidr)+('0'*(32-cidr))).scan(/.{8}/m).map{|e|e.to_i(2)}.join('.')
scroll top