我有以下十六进制数据格式:
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
请帮我修改一下代码
最佳答案
我猜解码后的值是一个转换为无符号的 64 位有符号二进制补码整数。在二进制补码机上,您可以使用以下命令将其强制转换:
$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
请注意,所使用的编码方案对于有符号数来说效率非常低。
关于regex - 如何在 Perl 中将十六进制解码为负整数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59333036/