Skip to content

Instantly share code, notes, and snippets.

@avocado3
Created May 5, 2012 15:06
Show Gist options
  • Save avocado3/2603141 to your computer and use it in GitHub Desktop.
Save avocado3/2603141 to your computer and use it in GitHub Desktop.
先頭アドレスとアドレス個数の組み合わせからビットマスクを用いたアドレス範囲に変換
#!/usr/bin/ruby
# ipv4aconv
# 先頭アドレスとアドレス個数の組み合わせからビットマスクを用いたアドレス範囲に変換
#
# 標準入力から”a.b.c.d,n”のリストを読み取り,アドレス範囲を書き出す
require 'ipaddr'
def ipv4aconv(ip, num)
ip = IPAddr.new(ip)
addr_ranges = []
loop do
# 先頭アドレスの後ろにあるゼロのビットを数える
z = ip.to_i != 0 ? 31 - ("%032b" % ip.to_i).rindex("1") : 32
# numに含まれる,2^zを超えない範囲で最大の2^mを求める
m = 0
m = m + 1 until 2**(m+1) > num || 2**(m+1) > 2**z
bitmask = 32 - m
addr_ranges.push(ip.to_s + "/" + bitmask.to_s)
break unless (num = num - 2**m) > 0
# アドレスに2^mを足して残りの分を計算する
# 第1引数がIntegerなのでアドレスファミリを明示する必要がある
# AF_INETがIPv4を表す(?)
ip = IPAddr.new(ip.to_i + 2**m, Socket::Constants::AF_INET)
end
addr_ranges
end
while line = $stdin.gets
ip, num = *line.rstrip.split(",")
print ipv4aconv(ip, num.to_i).join("\n") + "\n"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment