5

配列に格納された一連の IP アドレスがあります。

my @ip = qw(10.11.1.1 10.100.1.1 ...);

アドレスを昇順に並べ替えるにはどうすればよいですか? 私は簡単に試しましたsortが、もちろん失敗しました。

4

8 に答える 8

12

IPv4 アドレスは 32 ビットの数字です。

use Socket qw( inet_aton );
my @sorted =
    map substr($_, 4),
       sort
          map inet_aton($_) . $_,
             @ips;

また

my @sorted =
    map substr($_, 4),
       sort
          map pack('C4a*', split(/\./), $_),
             @ips;

最初のものもドメイン名を受け入れます。

于 2011-08-02T19:28:33.687 に答える
8

必要以上のことを想定したソリューションは好きではありません。私は以前からこの種のコンパクト表記に悩まされてきましたが、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;

これにより、コンパクトおよび範囲表記が適切に処理され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
于 2011-08-02T23:24:01.130 に答える
1

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 );
于 2011-08-02T19:22:33.633 に答える
1

Sort::Key::IPv4を使用する

于 2011-08-03T08:04:01.973 に答える
0

ソフトウェアのバージョン番号を並べ替えるように設計されたモジュールがあります。多分それはあなたが望むことをしますか?

于 2011-08-03T02:42:03.480 に答える
0

これで良いスタートが切れるはずです:

#!/usr/bin/perl

use strict;
use warnings;

sub Compare {
    # TODO: Error checking
    my @a  = split /\./, $a;
    my @b = split /\./, $b;
    # TODO: This might be cleaner as a loop
    return $a[0] <=> $b[0] ||
           $a[1] <=> $b[1] ||
           $a[2] <=> $b[2] ||
           $a[3] <=> $b[3];
}

my @ip = qw( 172.20.1.2 10.10.2.3 10.1.2.3 192.168.1.2 );

@ip = sort Compare @ip;

print join("\n", @ip), "\n";
于 2011-08-02T19:24:29.140 に答える