【发布时间】:2011-06-15 14:25:32
【问题描述】:
我有一个类似2001:db8::1 的标量地址,并希望获得扩展形式2001:0db8:0000:0000:0000:0000:0000:0001。主要的 Perl 软件包是否在 /usr/lib/perl5/... 的广阔森林中发布了一个已经可以执行此操作的模块?如果没有,是否有人有几行可以做到这一点?
【问题讨论】:
我有一个类似2001:db8::1 的标量地址,并希望获得扩展形式2001:0db8:0000:0000:0000:0000:0000:0001。主要的 Perl 软件包是否在 /usr/lib/perl5/... 的广阔森林中发布了一个已经可以执行此操作的模块?如果没有,是否有人有几行可以做到这一点?
【问题讨论】:
CPAN 有 Net::IP 可以满足您的需求。
以下是实际操作的成绩单:
$ cat qq.pl
use Net::IP;
$ip = new Net::IP ('2001:db8::1');
print $ip->ip() . "\n";
$ perl qq.pl
2001:0db8:0000:0000:0000:0000:0000:0001
【讨论】:
Net::IP 是纯 perl。我喜欢纯 perl 模块。
$ip = Net::IP::ip_expand_address('2001:db8::1', 6); 对我有用,不需要额外的对象。
Net::IP 绝对是一个不错的选择,因为它既简单又强大。但是,如果您要解析大量它们,您可能会考虑使用 Socket 包中的 inet_pton,因为它比 Net::IP 对象版本快 10-20 倍,即使预先创建了对象。并且比 ip_expand_address 版本快 4 倍:
use Net::IP;
use Time::HiRes qw(gettimeofday tv_interval);
use Socket qw(inet_pton AF_INET6);
use bignum;
use strict;
# bootstrap
my $addr = "2001:db8::1";
my $maxcount = 10000;
my $ip = new Net::IP($addr);
my ($t0, $t1);
my $res;
# test Net::IP
$t0 = [gettimeofday()];
for (my $i = 0; $i < $maxcount; $i++) {
$ip->set($addr);
$res = $ip->ip();
}
print "Net::IP elapsed: " . tv_interval($t0) . "\n";
print "Net::IP Result: $res\n";
# test non-object version
$t0 = [gettimeofday()];
for (my $i = 0; $i < $maxcount; $i++) {
$res = Net::IP::ip_expand_address('2001:db8::1', 6);
}
print "ip_expand elapsed: " . tv_interval($t0) . "\n";
print "ip_expand Result: $res\n";
# test inet_pton
$t0 = [gettimeofday()];
for (my $i = 0; $i < $maxcount; $i++) {
$res = join(":", unpack("H4H4H4H4H4H4H4H4",inet_pton(AF_INET6, $addr)));
}
print "inet_pton elapsed: " . tv_interval($t0) . "\n";
print "inet_pton result: " . $res . "\n";
在我的随机机器上运行此程序:
Net::IP elapsed: 2.059268
Net::IP Result: 2001:0db8:0000:0000:0000:0000:0000:0001
ip_expand elapsed: 0.482405
ip_expand Result: 2001:0db8:0000:0000:0000:0000:0000:0001
inet_pton elapsed: 0.132578
inet_pton result: 2001:0db8:0000:0000:0000:0000:0000:0001
【讨论】: