Nothing like a little intellectual exercise on a sunny sunday afternoon when normal people are at the beach :-)
package MAC;
use strict;
use warnings;
use Carp;
sub new
{
#constructor. Takes 1 argument besides the Class name, a MAC address
+ separated by colons(:)
# returns an object ref
my($class, $mac) = @_;
my $self = bless([], $class);
@{$self} = split(':', $mac);
unless($#{$self} == 5)
{
carp "failure to create MAC Object: address not composed of 6 byte
+s";
return;
}
my $c = 0;
foreach my $byte (@{$self})
{
#check for proper input values
unless($byte =~ /[0-9a-fA-F]{2}/)
{
carp "failure creating MAC Object: invalid address";
return;
}
#convert it to decimal, borrowed straight from the source of Data:
+:Translate
$byte = ord(unpack("A", pack("H*", $byte)));
@{$self}[$c] = $byte;
$c++;
}
return $self;
}
sub showdec
{
#takes no arguments. returns the mac address in decimal format, most
+ly for reference
my $self = shift;
return join(":", @{$self});
}
sub showhex
{
#takes no arguments. returns the mac address in hexadecimal format
my $self = shift;
return $self->_dectohex;
}
sub increase
{
#increases the mac address by argument. returns the newly increased
+address in hexadecimal format
my($self, $increase) = @_;
unless($increase =~ /^\d+$/)
{
carp "argument to \'increase\' must be a positive integer";
return;
}
$$self[5] += $increase;
for(my $c = 5; $c >= 1; $c--)
{
while($$self[$c] > 255)
{
$$self[$c] -= 256;
$$self[$c - 1] += 1;
}
}
return $self->_dectohex;
}
sub decrease
{
#decreases the mac address by argument. returns the newly decreased
+address in hexadecimal format
my($self, $decrease) = @_;
unless($decrease =~ /^\d+$/)
{
carp "argument to \'decrease\' must be a positive integer";
return;
}
$$self[5] -= $decrease;
for(my $c = 5; $c >= 1; $c--)
{
while($$self[$c] < 0)
{
$$self[$c] += 256;
$$self[$c - 1] -= 1;
}
}
return $self->_dectohex;
}
sub _dectohex
{
my $self = shift;
my @hexmac;
my $c = 0;
foreach my $byte (@{$self})
{
#convert to hex, this also borrowed (almost) straight from Data::T
+ranslate
$hexmac[$c] = sprintf("%02X", $byte);
$c++;
}
return join(":", @hexmac);
}
1;
and here's pretty much what I used to test it, which can also serve as a tiny example. Note that the module has 1 major shortcoming, neither increase nor decrease check whether the final address ends up below 00:00:00:00:00:00 or above FF:FF:FF:FF:FF:FF. I'll leave that as an exercise for the OP :-)
use strict;
use warnings;
use MAC;
my $mac = MAC->new('10:BE:AF:1C:06:1F');
print $mac->showdec . "\n";
print $mac->showhex . "\n";
print $mac->increase(10) . "\n";
print $mac->increase(65536) . "\n";
print $mac->decrease(256) . "\n";
print $mac->decrease(16777216) . "\n";
|