5

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

37 39 30 35 32 34 35 34 3B 32 31 36 39 39 33 34 35 35
32 31 31 31 36 39 39 33 34 36 00 08 408 40 00 00 00 00 15
6C 71 34 34 34 34 73 69 69 6D 31 5F 33 33 33 30 33 30 33 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 个字符?

4

3 回答 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
于 2010-08-05T03:48:35.347 回答
6

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

hex EXPR

hex

将 EXPR 解释为十六进制字符串并返回相应的值。(要转换可能以 、 或 开头的字符串00x0b参阅oct。)如果省略 EXPR,则使用$_.

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

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

$ perl -le '$_ = "ab c"; 打印拆分'
一种
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-输入
4196
于 2010-08-05T10:10:16.847 回答
0

我认为一次读取两个字符是解析逻辑标记为两个字符单元的流的适当方法。

你有什么理由认为这很丑吗?

如果您尝试提取特定序列,则可以使用不区分空格的正则表达式来完成。

于 2010-08-05T03:30:42.323 回答