Когда я пытаюсь упаковать более 5 байт с помощью шаблона «H2», я могу правильно распаковать первые 5 байт, но остальные повреждаются. Рассмотрим сценарий ниже:
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:", $_);
}
Выходы: 11:22:33:44:55:0а:
Последний байт выводится как «0a», а не как «66», как я ожидал.
Используйте Data::Dumper, чтобы увидеть, что содержат ваши переменные:
#!/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:", $_);
}
Выход:
$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:
Значение 102 слишком длинное, чтобы его можно было упаковать как H2, поэтому оно усекается. Вы получаете только 10
, что соответствует \20
восьмеричному, т.е. символу 16, который в шестнадцатеричном формате равен 10, что снова интерпретируется как шестнадцатеричное - 0a
.
Возможно, вы предполагали, что hex преобразует число в шестнадцатеричное, но происходит обратное. Может быть, вы изначально хотели этого?
#!/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;
pack H
требует шестнадцатеричного представления чисел, но вы указали числа.
Ваш код:
my $a = "11:22:33:44:55:66"; # Str ("11:22:33:44:55:66")
my @b = split /:/, $a; # Hex ("11", "22", "33", "44", "55", "66")
my @c = map { hex($_) } @b; # Nums (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
my $d = pack( "(H2)6", @c ); # XXX Expects hex by was provided nums.
Два способа починить упаковку:
my $a = "11:22:33:44:55:66"; # Str ("11:22:33:44:55:66")
my @b = split /:/, $a; # Hex ("11", "22", "33", "44", "55", "66")
my $d = pack( "(H2)6", @b ); # Bytes ("\x11\x22\x33\x44\x55\x66")
или
my $a = "11:22:33:44:55:66"; # Str ("11:22:33:44:55:66")
my @b = split /:/, $a; # Hex ("11", "22", "33", "44", "55", "66")
my @c = map { hex($_) } @b; # Nums (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
my $d = pack( "C6", @c ); # Bytes ("\x11\x22\x33\x44\x55\x66")
unpack H
возвращает шестнадцатеричный код, но вам нужны цифры.
Ваш код (с исправленным завершающим :
):
my $d = "\x11\x22\x33\x44\x55\x66"; # Bytes ("\x11\x22\x33\x44\x55\x66")
my @e = unpack( "(H2)6", $d ); # Hex ("11", "22", "33", "44", "55", "66")
my @f = map { sprintf("%02x", $_) } @e; # XXX Expects nums by was provided hex.
my $g = join( ":", @f );
Два способа исправить распаковку:
my $d = "\x11\x22\x33\x44\x55\x66"; # Bytes ("\x11\x22\x33\x44\x55\x66")
my @f = unpack( "(H2)6", $d ); # Hex ("11", "22", "33", "44", "55", "66")
my $g = join( ":", @f ); # Str ("11:22:33:44:55:66")
или
my $d = "\x11\x22\x33\x44\x55\x66"; # Bytes ("\x11\x22\x33\x44\x55\x66")
my @e = unpack( "C6", $d ); # Nums (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
my @f = map { sprintf("%02x", $_) } @e; # Hex ("11", "22", "33", "44", "55", "66")
my $g = join( ":", @f ); # Str ("11:22:33:44:55:66")
Вместе:
my $a = "11:22:33:44:55:66"; # Str ("11:22:33:44:55:66")
my @b = split /:/, $a; # Hex ("11", "22", "33", "44", "55", "66")
my $d = pack( "(H2)6", @b ); # Bytes ("\x11\x22\x33\x44\x55\x66")
my @f = unpack( "(H2)6", $d ); # Hex ("11", "22", "33", "44", "55", "66")
my $g = join( ":", @f ); # Str ("11:22:33:44:55:66")
или
my $a = "11:22:33:44:55:66"; # Str ("11:22:33:44:55:66")
my @b = split /:/, $a; # Hex ("11", "22", "33", "44", "55", "66")
my @c = map { hex($_) } @b; # Nums (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
my $d = pack( "C6", @c ); # Bytes ("\x11\x22\x33\x44\x55\x66")
my @e = unpack( "C6", $d ); # Nums (0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
my @f = map { sprintf("%02x", $_) } @e; # Hex ("11", "22", "33", "44", "55", "66")
my $g = join( ":", @f ); # Str ("11:22:33:44:55:66")