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?

Foi útil?

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, ou 0b, Vejo oct.) 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top