HEX dump parsing em Perl
Pergunta
Eu tenho um despejo hexadecimal de uma mensagem em um arquivo que eu quero obtê -lo em uma matriz para que eu possa executar a lógica de decodificação.
Eu queria saber se essa era uma maneira mais fácil de analisar uma mensagem que se parece com isso.
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
Observe que os dados podem ser max 16 bytes em qualquer linha. Mas qualquer linha também pode conter menos bytes (mínimo: 1)
Existe uma maneira agradável e elegante, em vez de ler 2 chars por vez em Perl?
Solução
Perl tem um hex
Operador que executa a lógica de decodificação para você.
hex EXPR
hex
Interpreta o Expr como uma string hexadecimal e retorna o valor correspondente. (Para converter strings que podem começar com qualquer
0
,0x
, ou0b
, Vejooct
.) Se expr for omitido, usa$_
.print hex '0xAf'; # prints '175' print hex 'aF'; # same
Lembre -se de que o comportamento padrão de split
Excha uma corda nos separadores de espaço em branco, por exemplo,
$ perl -le '$_ = "a b c"; print for split' a b c
Para cada linha da entrada, separe -a em valores hexadecimais, converta os valores em números e push
eles em uma matriz para processamento posterior.
#! /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";
Exemplo de execução:
$ ./sumhex mtanish-input 4196
Outras dicas
Eu lia uma linha de cada vez, retirava o espaço em branco e usava pack 'H*'
para convertê -lo. É difícil ser mais específico sem saber que tipo de "lógica de decodificação" você está tentando se aplicar. Por exemplo, aqui está uma versão que converte cada byte em decimal:
while (<>) {
s/\s+//g;
my @bytes = unpack('C*', pack('H*', $_));
print "@bytes\n";
}
Saída do seu arquivo de amostra:
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
Eu acho que ler em dois personagens de cada vez é a maneira apropriada de analisar um fluxo cujos tokens lógicos são unidades de dois caracteres.
Existe alguma razão pela qual você acha isso feio?
Se você está tentando extrair uma sequência específica, poderá fazer isso com expressões regulares insensíveis ao espaço em branco.