Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

pack function cannot pack more than 5 bytes

When I try to pack more than 5 bytes using "H2" template, I can unpack the first 5 correctly but the rest are corrupted. Consider the script below:

my $a = "11:22:33:44:55:66";
my @b = split /:/, $a;
my @c = map {hex($_)} @b;

my $d = pack( 'H2'x6, @c );

my @e = unpack( 'H2'x6, $d);
foreach (@e) {
    printf("%02x:", $_);
}

Outputs:
11:22:33:44:55:0a:

The last byte is output as "0a" and not "66" as I would have expected.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Use Data::Dumper to see what your variables contain:

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;

my $A = "11:22:33:44:55:66";  # $a is a special variable, don't use it.
my @b = split /:/, $A;
warn Dumper \@b;

my @c = map hex, @b;
warn Dumper \@c;

my $d = pack 'H2' x 6, @c;
{   local $Data::Dumper::Useqq = 1;
    warn Dumper $d;
}


my @e = unpack 'H2' x 6, $d;
warn Dumper \@e;

for (@e) {
    printf("%02x:", $_);
}

The output:

$VAR1 = [
          '11',
          '22',
          '33',
          '44',
          '55',
          '66'
        ];
$VAR1 = [
          17,
          34,
          51,
          68,
          85,
          102
        ];
$VAR1 = "\0274Qh\205\20";
$VAR1 = [
          '17',
          '34',
          '51',
          '68',
          '85',
          '10'
        ];
11:22:33:44:55:0a:

The value 102 is too long to be packed as H2, so it’s truncated. You only get 10, which corresponds to \20 octal, i.e. character 16, which in hex is 10, which again interpreted as hex is 0a.

It’s possible you assumed hex converts a number to hex, but it does the opposite. Maybe you originally wanted this instead?

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;

my $A = "11:22:33:44:55:66";
my @b = split /:/, $A;
warn Dumper \@b;

my @c = map sprintf('%02x', $_), @b;
warn Dumper \@c;

my $d = pack 'H2' x 6, @c;
{   local $Data::Dumper::Useqq = 1;
    warn Dumper $d;
}


my @e = unpack 'H2' x 6, $d;
warn Dumper \@e;

print hex, ':' for @e;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading