Ipaddress.rb
This content was produced by an LLM and could include errors.
このスクリプトはIPv4ユーティリティ集です。mask_to_cidr はマスクの1ビット数を数えてCIDRへ変換し(255.255.255.0 → 24)、cidr_to_mask は逆変換を行います。ip_address? は4オクテット・数値のみ・0〜255・先頭ゼロ禁止を検証し、subnet_mask? はビット列が「1の連続の後に0」となる形式か確認します。network_address? はホスト部ビットがすべて0かどうかでネットワークアドレスを判定します。
# frozen_string_literal: true
#=> nil
def mask_to_cidr(mask)
# count num of 1.
mask.split('.').sum { it.to_i.to_s(2).count('1') }
end
#=> :mask_to_cidr
p mask_to_cidr('255.255.255.0')
24
#=> 24
def cidr_to_mask(cidr)
# Repeat '1' cidr times and then pad with '0's to make 32 bits.
bits = '1' * cidr + '0' * (32 - cidr)
# split into chunks of 8 characters.
bits.scan(/.{8}/).map { it.to_i(2) }.join('.')
end
#=> :cidr_to_mask
p cidr_to_mask(24)
"255.255.255.0"
#=> "255.255.255.0"
def ip_address?(ip)
parts = ip.split('.')
return false unless parts.size == 4
parts.all? do |p|
return false unless p =~ /^\d+$/
num = p.to_i
return false if num.negative? || num > 255
return false if p != num.to_s # 先頭ゼロ防止
true
end
end
#=> :ip_address?
p ip_address?('127.0.0.1')
true
#=> true
def subnet_mask?(mask)
parts = mask.split('.')
return false unless parts.size == 4
binary = ''
parts.each do |p|
return false unless p =~ /^\d+$/
num = p.to_i
return false if num.negative? || num > 255
binary += num.to_s(2).rjust(8, '0')
end
# 1の後に0が続く形式のみ許可
return false if binary.include?('01')
# 全0 or 全1は除外
return false if binary == '0' * 32 || binary == '1' * 32
true
end
#=> :subnet_mask?
p subnet_mask?('255.0.0.0')
true
#=> true
def network_address?(ip, mask)
return false unless ip_address?(ip)
return false unless subnet_mask?(mask)
ip_parts = ip.split('.').map(&:to_i)
mask_parts = mask.split('.').map(&:to_i)
4.times do |i|
# ホスト部が0かチェック
return false if (ip_parts[i] & (~mask_parts[i] & 0xFF)) != 0
end
true
end
#=> :network_address?
p network_address?('10.0.0.0', cidr_to_mask(16))
true
#=> true
Ruby 4.0.6