使用perl将递增计数器打包为十六进制



我正在尝试创建一个12字节的头,我正在使用pack。一切都非常棒,直到我需要在pack函数中包含一个递增值。。

编辑:

我有一个打开的ffmpeg管道,我正在从中捕获输出。捕获的数据将是一个有效载荷,该有效载荷将被加密并附加到报头的末尾。我的循环不是for循环,但我想我会让读者更容易理解。

所以让我在这里更新这个问题,希望它能消除任何困惑。如果我需要提供更多信息,请告诉我。

my $m = 00;
my $n = 00;
while( <$source_audio> ) { 
if(($n % 16) == 0){
$m++; #this should increment when n reaches 0xff
}
my $header = pack( 'C C n n C*', 0x80, 0x78, $m, $n, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04 );
print $file $header ;
$n++;
}

我只需要能够打包$m和$n,这样我就可以得到预期的输出:

80 78 00 01 12 34 98 76 01 02 03 04
80 78 00 02 12 34 98 76 01 02 03 04
80 78 00 03 12 34 98 76 01 02 03 04
80 78 00 04 12 34 98 76 01 02 03 04
80 78 00 05 12 34 98 76 01 02 03 04
... iterating 0x0000 to 0xFFFF ...
80 78 FF FB 12 34 98 76 01 02 03 04
80 78 FF FC 12 34 98 76 01 02 03 04
80 78 FF FD 12 34 98 76 01 02 03 04
80 78 FF FE 12 34 98 76 01 02 03 04
80 78 FF FF 12 34 98 76 01 02 03 04

第2版:

这给了我想要的输出,但我在启用了严格和警告的情况下会出现错误:

my $m = 0x00;
my $n = 0x00;
my $message = "this";
while ( <$source_audio> ) {
my $header = pack('C*', 0x80, 0x78, $m, $n, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04);

if(($n % 0xFF) == 0 and $n != 0x00){
$m++;
}

$n++;
print $temp $header;
}
Character in 'C' format wrapped in pack

解决方案正是池上春树所指出的:

pack('C C n C*', 0x80, 0x78, $n, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04);

问题与pack或您对它的使用无关。问题是您计算错了$m$n。该警告是$m超过0xFF的结果,这显然不应该发生。

以下正确计算了$m$n(我将其重命名为$hi$lo,原因很快就会变得显而易见):

my $hi = 0x00;
my $lo = 0x00;
while ( <$source_audio> ) {
my $header = pack( 'C*',
0x80, 0x78, $hi, $lo, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04 );

...
if ( $lo == 0xFF ) {
$lo = 0;
++$hi;
} else {
++$lo;
}
}

这也可以写如下:

$lo = ( $lo + 1 ) & 0xFF;
++$hi if !$lo;

但我们实际上只是在增加一个存储在两个八位字节中的数字。

my $n = 0;
while ( <$source_audio> ) {
my $hi = $n >> 8;
my $lo = $n & 0xFF;
my $header = pack( 'C*',
0x80, 0x78, $hi, $lo, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04 );

...
++$n;
}

但让我们把包装留给pack吧!我们试图使用big-endian字节顺序将该值存储为16位无符号int。包装和开箱编号的咨询格式或pack的文档显示我们可以使用S>n

my $n = 0;
while ( <$source_audio> ) {
my $header = pack( 'C C n C*',
0x80, 0x78, $n, 0x12, 0x34, 0x98, 0x76, 0x01, 0x02, 0x03, 0x04 );

...
++$n;
}

最新更新