Я искал ответ @ ikegami, который сработал идеально, но я понятия не имел, почему.Поэтому я потратил пару мгновений, чтобы выяснить механику, лежащую в основе этого, и хочу поделиться своими заметками для дальнейшего использования для начинающих экспертов Perl ...
В этом примере я выбрал два очень специфических IP-адреса, потому что при кодировании какВ ASCII они будут выглядеть как ABCD
и EFGH
, как видно из вывода строки print Dumper()
.
Хитрость заключается в том, чтобы префикс каждой строки IP-адреса содержать 4 байта, содержащих ее двоичное представление.Затем записи сортируются и, наконец, префикс снова удаляется, оставляя список отсортированных IP-адресов.
Внутренняя работа описана в комментариях, лучше всего читать их в пронумерованном порядке.
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my @ips = qw( 69.70.71.72 65.66.67.68 );
print Dumper( map( pack( 'C4a*' , split( /\./ ) , $_ ) , @ips ) );
foreach my $ip (
map( # 5. For each IP address that was enriched with 32 bits representation ....
substr( $_ , 4) , # 6. Snip off the first four bytes as this is just a binary representation of the string, used for sorting.
sort( # 4. Sort will essentially work on the first 4 octets as these will represent the entire remainder of the string.
map( # 1. For each IP address in @ARGV ...
pack( 'C4a*' , # 3. Change ASCII encoded octets from the IP address into a 32 bit 'string' (that can be sorted) and append it with the original IP address string for later use.
split( /\./ ), $_ ) , # 2. Split the IP address in separate octets
@ips # 0. Unsorted list of IP addresses.
)
)
)
) {
print "$ip\n";
}
Вывод будет выглядеть следующим образом:
$VAR1 = 'EFGH69.70.71.72';
$VAR2 = 'ABCD64.65.66.67';
64.65.66.67
69.70.71.72
Где первые две строки от print Dumper()
, который показывает, что IP-адреса имеют префикс 32-битного представления числового IP-адреса.адреса.