Ruby IPAddr:查找地址掩码
Ruby IPAddr: find address mask
我有一个处理大量 IP 地址的应用程序(分析 Checkpoint 防火墙规则集)。有一次我想检查一个特定的地址对象是 /32 还是 'network'.
目前我是这样做的:
next unless ip.inspect.match(/\/255\.255\.255\.255/)
它有效,但似乎有点低效,但我看不到任何从地址对象中提取掩码的方法。
Ruby 核心库的某些部分有时只是草拟,IPAddr 似乎是其中之一,不幸的是,有点不完整。
不用担心。你可以用一个简单的 monkey-patch:
来解决这个问题
class IPAddr
def cidr_mask
case (@family)
when Socket::AF_INET
32 - Math.log2((1<<32) - @mask_addr).to_i
when Socket::AF_INET6
128 - Math.log2((1<<128) - @mask_addr).to_i
else
raise AddressFamilyError, "unsupported address family"
end
end
end
应该处理 IPv4 和 IPv6 地址:
IPAddr.new('151.101.65.69').cidr_mask
# => 32
IPAddr.new('151.101.65.69/26').cidr_mask
# => 26
IPAddr.new('151.101.65.69/255.255.255.0').cidr_mask
# => 24
IPAddr.new('2607:f8b0:4006:800::200e').cidr_mask
# => 128
IPAddr.new('2607:f8b0:4006:800::200e/100').cidr_mask
# => 100
这里不一定是最好的解决方案,但它确实有效。
我知道这是一个 3 年前的问题,但这是我在 Google 上搜索时的第一个结果,所以我想提供一个新答案。
我今天在控制台上玩,注意到 IPAddr
对象 returns cidr 掩码上的 prefix
方法是一个整数。
因此,例如:
ip = IPAddr.new("192.168.1.0/24")
ip.prefix
# => 24
事实证明,类型强制为您提供了地址和掩码的整数表示,因此您可以对 to_i
、to_json
、[=17= 的输出进行数学计算] 或 instance_values
.
网络地址示例:
ip.to_i
# => 3232235776
ip.to_i.to_s(2)
# => "11000000101010000000000100000000"
还有一个带有网络掩码:
ip.as_json
# => {"family"=>2, "addr"=>3232235776, "mask_addr"=>4294967040}
ip.as_json["mask_addr"].to_s(2)
# => 11111111111111111111111100000000
ip.as_json["mask_addr"].to_s(2).count("1")
# => 24
我有一个处理大量 IP 地址的应用程序(分析 Checkpoint 防火墙规则集)。有一次我想检查一个特定的地址对象是 /32 还是 'network'.
目前我是这样做的:
next unless ip.inspect.match(/\/255\.255\.255\.255/)
它有效,但似乎有点低效,但我看不到任何从地址对象中提取掩码的方法。
Ruby 核心库的某些部分有时只是草拟,IPAddr 似乎是其中之一,不幸的是,有点不完整。
不用担心。你可以用一个简单的 monkey-patch:
来解决这个问题class IPAddr
def cidr_mask
case (@family)
when Socket::AF_INET
32 - Math.log2((1<<32) - @mask_addr).to_i
when Socket::AF_INET6
128 - Math.log2((1<<128) - @mask_addr).to_i
else
raise AddressFamilyError, "unsupported address family"
end
end
end
应该处理 IPv4 和 IPv6 地址:
IPAddr.new('151.101.65.69').cidr_mask
# => 32
IPAddr.new('151.101.65.69/26').cidr_mask
# => 26
IPAddr.new('151.101.65.69/255.255.255.0').cidr_mask
# => 24
IPAddr.new('2607:f8b0:4006:800::200e').cidr_mask
# => 128
IPAddr.new('2607:f8b0:4006:800::200e/100').cidr_mask
# => 100
这里不一定是最好的解决方案,但它确实有效。
我知道这是一个 3 年前的问题,但这是我在 Google 上搜索时的第一个结果,所以我想提供一个新答案。
我今天在控制台上玩,注意到 IPAddr
对象 returns cidr 掩码上的 prefix
方法是一个整数。
因此,例如:
ip = IPAddr.new("192.168.1.0/24")
ip.prefix
# => 24
事实证明,类型强制为您提供了地址和掩码的整数表示,因此您可以对 to_i
、to_json
、[=17= 的输出进行数学计算] 或 instance_values
.
网络地址示例:
ip.to_i
# => 3232235776
ip.to_i.to_s(2)
# => "11000000101010000000000100000000"
还有一个带有网络掩码:
ip.as_json
# => {"family"=>2, "addr"=>3232235776, "mask_addr"=>4294967040}
ip.as_json["mask_addr"].to_s(2)
# => 11111111111111111111111100000000
ip.as_json["mask_addr"].to_s(2).count("1")
# => 24