<<, | and/or & are forcing an integer context. The float or double that my Perl (Win32) uses can hold a 48 bit integer with no loss of precision, so you could rewrite your code to avoid using operators that force Perl to work with integers. What follows is such code:
sub mac_hex2num {
my $mac_hex = shift;
$mac_hex =~ s/://g;
$mac_hex = substr(('0'x12).$mac_hex, -12);
my @mac_bytes = unpack("A2"x6, $mac_hex);
my $mac_num = 0;
foreach (@mac_bytes) {
$mac_num = $mac_num * (2**8) + hex($_);
}
return $mac_num;
}
sub mac_num2hex {
my $mac_num = shift;
my @mac_bytes;
for (1..6) {
unshift(@mac_bytes, sprintf("%02x", $mac_num % (2**8)));
$mac_num = int($mac_num / (2**8));
}
return join(':', @mac_bytes);
}
chomp(my $inmac = shift @ARGV);
my $mac = mac_hex2num($inmac);
print "$inmac converted to a decimal: $mac\n";
my $outmac = mac_num2hex($mac);
print "$mac converted to hex: $outmac\n";
__END__
>perl mac2num.pl FEDCBA98765F
FEDCBA98765F converted to a decimal: 280223976814175
280223976814175 converted to hex: fe:dc:ba:98:76:5f
>perl mac2num.pl 2500998230
2500998230 converted to a decimal: 158923850288
158923850288 converted to hex: 00:25:00:99:82:30
>perl mac2num.pl FFFFFFFFFFFF
FFFFFFFFFFFF converted to a decimal: 281474976710655
281474976710655 converted to hex: ff:ff:ff:ff:ff:ff
By the way, you had a bug when fewer than 12 digits were provided. "2500998230" was being treated as "0x250099820030" instead of "0x002500998230". The substr business in mac_hex2num fixes the problem.
|