- 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)) ];
- }