我有一堆存储在数组中的IP地址,例如:
my @ip = qw(10.11.1.1 10.100.1.1 ...);
Run Code Online (Sandbox Code Playgroud)
如何按升序对地址进行排序?我尝试过一个简单的sort
但当然失败了.
ike*_*ami 11
IPv4地址只是32位数字.
use Socket qw( inet_aton );
my @sorted =
map substr($_, 4),
sort
map inet_aton($_) . $_,
@ips;
Run Code Online (Sandbox Code Playgroud)
要么
my @sorted =
map substr($_, 4),
sort
map pack('C4a*', split(/\./), $_),
@ips;
Run Code Online (Sandbox Code Playgroud)
第一个也接受域名.
我不喜欢任何能够满足需要的解决方案.我之前通过紧凑的表示法对这种事情进行了刻录,我认为当IPv6变得更加普遍时,这个问题会变得更加严峻.我只想让Net :: IP搞清楚:
use 5.010;
use Net::IP;
my @ip = qw(
192.168.1.10
172.16.5.5
256.0.0.1
192.168.1/24
127.1
127.0.1
fd00:6587:52d7:f8f7:5a55:caff:fef5:af31
fd24:cd9b:f001:884c:5a55:caff:fef5:af31
);
my @sorted =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, eval { Net::IP->new( $_ )->intip } ] }
@ip;
say join "\n", @sorted;
Run Code Online (Sandbox Code Playgroud)
这样可以很好地处理紧凑和范围符号,并eval
捕获错误的IP地址.我不必单独处理IPv4和IPv6:
256.0.0.1
127.0.1
127.1
172.16.5.5
192.168.1/24
192.168.1.10
fd00:6587:52d7:f8f7:5a55:caff:fef5:af31
fd24:cd9b:f001:884c:5a55:caff:fef5:af31
Run Code Online (Sandbox Code Playgroud)
只是 IPv4 地址吗?
my @ip = map $_->[0],
sort { $a->[1] cmp $b->[1] }
map [ $_, join '', map chr, split /\./, $_ ],
qw( 10.1.2.3 172.20.1.2 192.168.1.2 );
Run Code Online (Sandbox Code Playgroud)