我在文件中有一个消息的十六进制转储,我希望在数组中获取它 所以我可以对它执行解码逻辑 我想知道这是否是一种解析看起来像这样的消息的简单方法。
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个字符?
答案 0 :(得分: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
答案 1 :(得分:6)
Perl有一个hex
运算符,可以为您执行解码逻辑。
hex EXPR
hex
将EXPR解释为十六进制字符串并返回相应的值。 (要转换可能以
0
,0x
或0b
开头的字符串,请参阅oct
。)如果省略EXPR,请使用$_
。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
答案 2 :(得分:0)
我认为一次读两个字符是解析逻辑令牌为双字符单元的流的合适方法。
你有什么理由觉得这很丑吗?
如果您尝试提取特定序列,则可以使用空格不敏感的正则表达式来执行此操作。