Perl中的十六进制转储解析

5
我有一个文件中的消息十六进制转储,我希望将其放入数组中,以便可以对其执行解码逻辑。
我想知道是否有一种更简单的解析消息的方法,消息看起来像这样。

37 39 30 35 32 34 35 34 3B 32 31 36 39 33 34 35
3B 32 31 36 39 33 34 36 00 00 01 08 40 00 00 15
6C 71 34 34 73 69 6D 31 5F 33 30 33 31 00 00 00
00 00 01 28 40 00 00 15 74 65 6C 63 6F 72 64 69
74 65 6C 63 6F 72 64 69

请注意,任何一行的数据最多只能为16字节。但是任何一行也可能包含较少的字节(最少:1)
是否有一种漂亮而优雅的方式,而不是在perl中每次读取2个字符?
3个回答

6

我会逐行读取文本,去除空格,并使用 pack 'H*' 进行转换。如果您不知道需要应用什么样的“解码逻辑”,那就很难提供更加具体的信息。例如,以下版本将每个字节转换为十进制:

while (<>) {
  s/\s+//g;
  my @bytes = unpack('C*', pack('H*', $_));
  print "@bytes\n";
}

您样例文件的输出结果:

55 57 48 53 50 52 53 52 59 50 49 54 57 51 52 53
59 50 49 54 57 51 52 54 0 0 1 8 64 0 0 21
108 113 52 52 115 105 109 49 95 51 48 51 49 0 0 0
0 0 1 40 64 0 0 21 116 101 108 99 111 114 100 105
116 101 108 99 111 114 100 105

6
Perl有一个hex运算符,可以为您执行解码逻辑。

hex EXPR

hex

Interprets EXPR as a hex string and returns the corresponding value. (To convert strings that might start with either 0, 0x, or 0b, see oct.) If EXPR is omitted, uses $_.

print hex '0xAf'; # prints '175'
print hex 'aF'; # same

请记住,split的默认行为是将字符串在空格分隔符处分割,例如:

$ perl -le '$_ = "a b c"; print for split'
a
b
c

对于输入的每一行,将其分成十六进制值,将这些值转换为数字,并将它们push到一个数组中以供以后处理。

#! /usr/bin/perl

use warnings;
use strict;

my @values;
while (<>) {
  push @values => map hex($_), split;
}

# for example
my $sum = 0;
$sum += $_ for @values;
print $sum, "\n";

示例运行:

$ ./sumhex mtanish-input 
4196

0

我认为一次读取两个字符是解析逻辑令牌为两个字符单位的流的适当方式。

你认为这有什么不好吗?

如果你想提取特定的序列,你可以使用忽略空格的正则表达式来实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接