use strict;
use Test::More;
use NetAddr::IP::Lite;
#use NetAddr::IP::Util qw(
# bcd2bin
# ipv6_n2x
# bin2bcd
#);
#use Data::Dumper;
my @num = qw(
2001:468:D01:3C:0:0:80DF:3C1B/128 42540577535367674011024906890208295963
73.150.6.197/32 1234568901
128.0.0.0/32 2147483648
0:0:0:0:0:1:0:0/128 4294967296
0:0:0:0:0:2:0:0/128 8589934592
0:0:0:0:0:2:540B:E400/128 10000000000
0:0:0:0:0:4:0:0/128 17179869184
0:0:0:0:0:8:0:0/128 34359738368
0:0:0:0:0:10:0:0/128 68719476736
0:0:0:0:0:20:0:0/128 137438953472
0:0:0:0:0:40:0:0/128 274877906944
0:0:0:0:0:80:0:0/128 549755813888
0:0:0:0:0:100:0:0/128 1099511627776
0:0:0:0:0:200:0:0/128 2199023255552
0:0:0:0:0:400:0:0/128 4398046511104
0:0:0:0:0:800:0:0/128 8796093022208
0:0:0:0:0:1000:0:0/128 17592186044416
0:0:0:0:0:2000:0:0/128 35184372088832
0:0:0:0:0:4000:0:0/128 70368744177664
0:0:0:0:0:8000:0:0/128 140737488355328
0:0:0:0:8000:0:0:0/128 9223372036854775808
0:0:0:8000:0:0:0:0/128 604462909807314587353088
0:0:8000:0:0:0:0:0/128 39614081257132168796771975168
0:8000:0:0:0:0:0:0/128 2596148429267413814265248164610048
8000:0:0:0:0:0:0:0/128 170141183460469231731687303715884105728
255.255.255.255/32 4294967295
1.2.3.4/32 16909060
10.253.230.9/32 184411657
);
plan tests => scalar @num;
#diag ("\ntesting SCALARS\n\n");
for(my $i = 0;$i <= $#num;$i += 2) {
my $n = $num[$i +1];
my $ip = new NetAddr::IP::Lite($n);
ok($ip eq $num[$i],"$n\t=> got: $ip\texp: ". $num[$i]);
}
#diag ("\ntesting Math::BigInt's\n\n");
for(my $i = 0;$i <= $#num;$i += 2) {
my $n = new Math::BigInt($num[$i +1]);
my $ip = new NetAddr::IP::Lite($num[$i +1]);
ok($ip eq $num[$i],"$n\t=> got: $ip\texp: ". $num[$i]);
}
# simulate the use of Math::BigInt
package Math::BigInt;
use strict;
use overload
'""' => sub { $_[0]->_str(); };
sub BASE_LEN () { 7 };
sub _str { # adapted from Math::BigInt::Calc::_str
# (ref to BINT) return num_str
# Convert number from internal base 100000 format to string format.
# internal format is always normalized (no leading zeros, "-0" => "+0")
my $ar = $_[0]->{value};
my $l = scalar @$ar; # number of parts
my $ret = "";
# handle first one different to strip leading zeros from it (there are no
# leading zero parts in internal representation)
$l --; $ret .= int($ar->[$l]); $l--;
# Interestingly, the pre-padd method uses more time
# the old grep variant takes longer (14 vs. 10 sec)
my $z = '0' x (BASE_LEN -1);
while ($l >= 0)
{
$ret .= substr($z.$ar->[$l],- BASE_LEN); # fastest way I could think of
$l--;
}
$ret;
}
sub new { # adapted from Math::BigInt::new
my ($class,$wanted) = @_;
my $self = bless {}, $class;
die "oops, not a good Math::BigInt number"
unless ((!ref $wanted) && ($wanted =~ /^([+-]?)[1-9][0-9]*\z/));
$self->{sign} = $1 || '+';
if ($wanted =~ /^[+-]/) {
# remove sign without touching wanted to make it work with constants
my $t = $wanted; $t =~ s/^[+-]//;
$self->{value} = _new($t);
}
else {
$self->{value} = _new($wanted);
}
return $self;
}
sub _new { # adapted from Math::BigInt::Calc::_new
my $wanted = $_[0];
# (ref to string) return ref to num_array
# Convert a number from string format (without sign) to internal base
# 1ex format. Assumes normalized value as input.
my $il = length($wanted)-1;
# < BASE_LEN due len-1 above
return [ int($wanted) ] if $il < BASE_LEN; # shortcut for short numbers
my $base_len = BASE_LEN;
# this leaves '00000' instead of int 0 and will be corrected after any op
[ reverse(unpack("a" . ($il % BASE_LEN +1)
. ("a$base_len" x ($il / BASE_LEN)), $wanted)) ];
}