I want to encode numbers in N bit containers and send them in a UDP packet. A receiver will know N, and the receiver will grab a number from exactly N bits.(N <= 64)
Somethink like this:
sub to56BIT {
return pack("??", shift);
}
sub to24BIT {
return pack("??", shift);
}
my $n = 7;
to24BIT($n);
On the receiver's side:
int n = Get_val24(byte_stream, offset);
Is there any way to do this in Perl?
I think solution might be:
sub packIntN {
my $int = shift;
my $length = shift;
return pack("B" . $length, substr(unpack("B64", pack("Q>", $int)), 64 - $length));
}
But maybe there is more elegant way.
Input/Output example: We have a script test.pl:
use strict;
use warnings;
sub to24BIT {
#???
}
my $n = 7;
print to24BIT($n);
I want this:
./test.pl | hexdump -C
00000000 00 00 07 |...|
00000003
Another script test2.pl:
use strict;
use warnings;
sub to40BIT {
#???
}
my $n = 7;
print to40BIT($n);
I want this:
./test.pl | hexdump -C
00000000 00 00 00 00 07 |.....|
00000005
Is N always going to be an integer factor of 8 (one of 8, 16, 24, 32, 40, 48, 56, 64)? If so, for speed, I recommend writing a packer for each size and use a dispatch table to find the right packer.
sub pack_8bit { pack('C', $_[0]) }
sub pack_16bit { pack('S>', $_[0]) }
sub pack_24bit { substr(pack('L>', $_[0]), 1) }
sub pack_32bit { pack('L>', $_[0]) }
sub pack_40bit { substr(pack('Q>', $_[0]), 3) }
sub pack_48bit { substr(pack('Q>', $_[0]), 2) }
sub pack_56bit { substr(pack('Q>', $_[0]), 1) }
sub pack_64bit { pack('Q>', $_[0]) }
{
my %packers = (
8 => \&pack_8bit, 40 => \&pack_40bit,
16 => \&pack_16bit, 48 => \&pack_48bit,
24 => \&pack_24bit, 56 => \&pack_56bit,
32 => \&pack_32bit, 64 => \&pack_64bit,
);
sub pack_num {
my $packer = $packers{$_[0]}
or die;
return $packer->($_[1]);
}
sub get_packer {
my $packer = $packers{$_[0]}
or die;
return $packer;
}
}
my $packed = pack_num(40, 7);
-or-
my $packer = get_packer(40);
my $packed = $packer->(7);
If you're planning on packing multiple numbers into one string (like pack('L>*', @nums)
), I'd also use a dispatch table like this, though I'm not sure what would be the fastest implementation of pack_24bit
, pack_40bit
, pack_48bit
and pack_56bit
(other than a C solution).