我有一个应用程序,我处理大量IP地址(分析Checkpoint防火墙规则集)。有一次,我想检查一个特定的地址对象是/ 32还是“网络”。
目前我这样做:
next unless ip.inspect.match(/\/255\.255\.255\.255/)
它有效,但看起来效率有点但我看不到任何从地址对象中提取掩码的方法。
答案 0 :(得分:5)
Ruby核心库的某些部分有时只是勾勒出来的,而IPAddr似乎是其中之一,不幸的是,它有点不完整。
不用担心。你可以用一个简单的猴子补丁解决这个问题:
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
这不一定是最好的解决方案,但它确实有效。
答案 1 :(得分:0)
我知道这是一个已有3年历史的问题,但这是我在Google上搜索到的第一个结果,因此我想提供一个新答案。
我今天在控制台上玩耍,发现prefix
对象上的IPAddr
方法返回cidr mask作为整数。
例如,
ip = IPAddr.new("192.168.1.0/24")
ip.prefix
# => 24
结果还表明,强制类型为您提供了地址和掩码的整数表示形式,因此您可以对to_i
,to_json
,as_json
或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
答案 2 :(得分:-3)
对于您筹集的特定情况,您可以这样做:
my $sql2 = "SELECT CODE_ID,NAME_CODE,SUM(INR_COL + OUT_COL) AS \"TOTAL SUM\" FROM nwsa WHERE trunc(REPORT_DATE) = to_date('?','dd-mm-yyyy')AND CODE_ID IN (?,?,?,?,?,?,?,?,?,?,?)GROUP BY CODE_ID,NAME_CODE";
$sth ->prepare($sql2);
my $t= "06-01-2017";
$sth->execute($t,'A12A','A12B','A12C','A12D','A12E','A12EB','A12F','A12G','A12I','A12O','A12U');
也许这种简单的比较比使用正则表达式测试字符串更有效。