#!/usr/bin/perl
##################################
# CONVERT IPSCOUNTRY.DAT TO TXT #
##################################
my $ipstxt_fl = $ARGV[0] || './ips-ascii.txt' ;
my $ipsdb_fl = $ARGV[1] || './ipscountry.dat' ;
my $HEADERS_BLKS = 256 ;
my @baseX = qw(0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z . , ; ' " ` < > { } [ ] = + - ~ * @ # % $ & ! ?) ;
my (%baseX,$base) ;
####################
# DECLARE BASE LIB #
####################
{
my $c = 0 ;
%baseX = map { $_ => ($c++) } @baseX ;
$base = @baseX ;
foreach my $Key ( keys %countrys ) { $countrys{$Key} =~ s/_/ /gs ;}
}
########
# HELP #
########
if ( $ARGV[0] =~ /^-+h/i || $#ARGV < 1 ) {
print qq`
_________________________________________________________
This tool will convert the ASCII database (from ipct2txt)
to Geo::IPfree dat file.
USE: perl $0 ./ips-ascii.txt ./ipscountry.dat
Enjoy! :-P
_________________________________________________________
`;
exit ;
}
########
# INIT #
########
my @DB ;
print "Reading...\n" ;
open (LOG,$ipstxt_fl) ;
while ($line = <LOG>) {
my ($country,$ip0,$ip1) = ( $line =~ /([\w-]{2}):\s+(\d+\.\d+\.\d+\.\d+)\s+(\d+\.\d+\.\d+\.\d+)/gs );
my $range = ip2nb($ip0) ;
my $iprange = dec2baseX($range);
push(@DB , "$country$iprange") ;
}
close (LOG) ;
@DB = reverse @DB ;
my %headers ;
my (%headers,$c) ;
my $pos = 0 ;
my $blk_sz = int ( ($#DB+1) / $HEADERS_BLKS ) ;
print "BLK size: $blk_sz\n" ;
foreach my $DB_i ( @DB ) {
if ($c == 0) {
#my $country = substr($DB_i , 0 , 2) ;
my $iprange = substr($DB_i , 2) ;
my $range = baseX2dec($iprange) ;
$headers{$range} = $pos ;
}
$c++ ;
if ($c >= $blk_sz) { $c = 0 ;}
$pos+=7 ;
}
print "Saving...\n" ;
open (NEWLOG,">$ipsdb_fl") ;
my $sel= select(NEWLOG); $|=1; select($sel);
my $date = &get_date ;
print NEWLOG qq`###############################################################
## IPs COUNTRY DATABASE ($date) ##
###############################################################
## This is the database used in the Perl module GeoIPfree. ##
## ##
## FORMAT: ##
## ##
## the DB has a list of IP ranges & countrys, for ##
## example, from 200.128.0.0 to 200.103.255.255 the IPs ##
## are from BR. To make a fast access to the DB the ##
## format try to use less bytes per input (block). The ##
## file was in ASCII and in blocks of 7 bytes: XXnnnnn ##
## ##
## XX -> the country code (BR,US...) ##
## nnnnn -> the IP range using a base of 85 digits ##
## (not in dec or hex to get space). ##
## ##
## To convert this file to another format see the tool ##
## ipct2txt.pl in the same directory of Geo/IPfree.pm ##
## ##
## See CPAN for updates... ##
###############################################################
`;
print NEWLOG "\n##headers##" ;
my $headers ;
foreach my $Key (sort {$b <=> $a} keys %headers ) {
$headers .= "$Key=$headers{$Key}#" ;
}
print NEWLOG length($headers) . "##$headers" ;
print NEWLOG "\n\n##start##" ;
foreach my $DB_i ( @DB ) { print NEWLOG $DB_i ;}
print "\nOK! $ipsdb_fl created\n" ;
############
# GET_DATE #
############
sub get_date {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon++ ;
$year += 1900 ;
$sec = "0$sec" if $sec < 10 ;
$min = "0$min" if $min < 10 ;
$hour = "0$hour" if $hour < 10 ;
$mday = "0$mday" if $mday < 10 ;
$mon = "0$mon" if $mon < 10 ;
return( "$year-$mon-$mday $hour:$min:$sec" ) ;
}
#########
# IP2NB #
#########
sub ip2nb {
my @ip = split(/\./ , $_[0]) ;
#return( 16777216* $ip[0] + 65536* $ip[1] + 256* $ip[2] + $ip[3] ) ;
return( ($ip[0]<<24) + ($ip[1]<<16) + ($ip[2]<<8) + $ip[3] ) ;
}
#########
# NB2IP #
#########
sub nb2ip {
my ( $ipn ) = @_ ;
my @ip ;
my $x = $ipn ;
while($x > 1) {
my $c = $x / 256 ;
my $ci = int($x / 256) ;
#push(@ip , $x - ($ci*256)) ;
push(@ip , $x - ($ci<<8)) ;
$x = $ci ;
}
push(@ip , $x) if $x > 0 ;
while( $#ip < 3 ) { push(@ip , 0) ;}
@ip = reverse (@ip) ;
return( join (".", @ip) ) ;
}
#############
# DEC2BASEX #
#############
sub dec2baseX {
my ( $dec ) = @_ ;
my @base ;
my $x = $dec ;
while($x > 1) {
my $c = $x / $base ;
my $ci = int($x / $base) ;
push(@base , $x - ($ci*$base) ) ;
$x = $ci ;
}
push(@base , $x) if $x > 0 ;
while( $#base < 4 ) { push(@base , 0) ;}
my $baseX ;
foreach my $base_i ( reverse @base ) {
$baseX .= $baseX[$base_i] ;
}
return( $baseX ) ;
}
#############
# BASEX2DEC #
#############
sub baseX2dec {
my ( $baseX ) = @_ ;
my @base = split("" , $baseX) ;
my $dec ;
my $i = -1 ;
foreach my $base_i ( reverse @base ) {
$i++ ;
$dec += $baseX{$base_i} * ($base**$i) ;
}
return( $dec ) ;
}
#######
# END #
#######
syntax highlighted by Code2HTML, v. 0.9.1