如何在Perl中将十六进制解码为负整数值

问题描述 投票:3回答:1

我具有以下十六进制数据格式:

9BDCE310
B4D9F1E502
EAB1A9C607
88EE8EB9F9FFFFFFFF01
9E828D89FCFFFFFFFF01

通常,我使用以下代码解码回整数:

sub decodeInt
{
    $_[0] =~ s/^([\x80-\xFF]*[\x00-\x7F])// or return;

    my $encoded_num = $1;
    my $num = 0;
    for ( reverse unpack 'C*', $encoded_num )
    {
        $num = ( $num << 7 ) | ( $_ & 0x7F );
    }

    return $num;
}

但是它不适用于带符号的负整数值(最后2个数据)。

88EE8EB9F9FFFFFFFF01
9E828D89FCFFFFFFFF01

请帮助我修改代码。

regex perl hex
1个回答
2
投票
$num = unpack 'q', pack 'Q', $num;

例如,

use strict;
use warnings;
use feature qw( say );

use Config qw( %Config );

sub decode_int {
    my ($encoded_num) = @_;

    my $num = 0;
    $num = ( $num << 7 ) | ( $_ & 0x7F )
       for reverse unpack 'C*', $encoded_num;

    $num = unpack 'q', pack 'Q', $num;

    return $num;
}

{
   $Config{ivsize} >= 8 && $Config{uvsize} >= 8
      or die("64-bit int support required\n");

   say decode_int(pack('H*', $_))
      for qw(
         9BDCE310
         B4D9F1E502
         EAB1A9C607
         88EE8EB9F9FFFFFFFF01
         9E828D89FCFFFFFFFF01
      );
}

输出

35188251
750546100
2026526954
-1759267064
-1054654178

请注意,所使用的编码方案对带符号的数字非常无效。

© www.soinside.com 2019 - 2024. All rights reserved.