18 Oct

Geolocalizar un listado de IPs con Perl

El otro día un cliente nos hizo el encargo de obtener los países a los que pertenecían un listado de IPs de un log. Bueno, pues usamos cualquier servicio de geolocalización de IPs y solucionado. El problema vino cuando el archivo tenía miles de IPs, de modo que era inviable hacerlo a mano. Así que para estos casos PERL viene de PERLas.
Bien, lo primero es tener instalado PERL en nuestra distribución de Linux favorita (sí, PERL se programa en Linux ^_^). Y mediante CPAN instalamos el módulo IP-Country, desde una terminal:

loquesea@loquesea:~$ sudo perl -MCPAN -e shell 
loquesea@loquesea:~$ install IP::Country

El archivo de entrada será un simple txt con una IP por cada línea, por ejemplo:

106.10.85.67
109.166.128.6
109.174.113.164
111.243.39.145
112.134.171.139
...

Y el código PERL:

#!/usr/bin/perl
use IP::Country::Fast;

my $ips= "ips.txt"; #Archivo de entrada con una IP en cada línea
my $paises="paises.txt"; #Archivo de salida con el número de IPs por país

open (ENTRADA,"<$ips") or (die "ERROR: No puedo abrir el fichero $ips\n"); 
open (SALIDA,">$paises") or (die "ERROR: No puedo abrir el fichero $paises\n");

my $reg = IP::Country::Fast->new();
my %hashPaises; # Hash contador de veces que aparece cada país

while (){ #Recorremos línea a línea
  $ip=$_; 
  chomp $ip; #Eliminamos el salto de línea
  $pais = $reg->inet_atocc($ip); #Obtenemos el país asociado a la IP
  $hashPaises{$pais}++; #Sumamos el contador de país 
  #print SALIDA ($ip."\t".$pais."\n"); #Si quisieramos imprimir cada IP a qué país pertenece, en mi caso eran demasiadas
}

foreach $pais (sort {$hashPaises{$a} <=> $hashPaises{$b} } keys %hashPaises){ #Imprimimos cada país con su cantidad de ocurrencias ordenado de menor a mayor
     print SALIDA "$pais $hashPaises{$pais}\n";
}

close ENTRADA;
close SALIDA;

Le damos permisos de ejecución, y lo ejecutamos:

loquesea@loquesea:~$ chmod 777 geolocaliza.pl
loquesea@loquesea:~$ ./geolocaliza.pl

Y la salida de nuestro programa se escribirá en paises.txt:

DE 9
VN 11
IN 17
UA 18
ES 21
US 22
BY 23
RU 31
...

Comparte

Responder