Как я могу разобрать разделенные пробелами шестнадцатеричные строки STDIN, распакованные в Perl?
у меня есть Java-программа, которая выплевывает в шестнадцатеричном формате с разделением пространства 16 байтов необработанного пакета, полученного по сети. Поскольку я не хочу изменять этот код, я передаю результат скрипту Perl, который теоретически может просто unpack
этого STDIN
в узнаваемых переменных. Ниже приведен пример ввода строки в мой файл Perl:
FF FF 09 7D 10 01 07 01 00 02 00 1D 00 00 00 00 00 06 00 07 00 |--garbage-----|c--|c--|int---|int---|int---|int---|int---|int---|int---|
(c для char / byte, int для 16-битной целочисленной переменной)
Я изначально хотел использовать unpack
чтобы четко разделить каждую входную строку на переменные, которые мне нужны. Однако из-за разделителя пространства в строке я не уверен, как его обрабатывать (я могу использовать " A " в качестве шаблона, но тогда я мог бы просто использовать split!)
есть ли элегантный способ использования unpack()
? Я не мастер Perl, но другой способ, как я предлагал раньше, использовать split
а затем вручную преобразовать каждый hex в байт, а затем использовать битовые манипуляции и маски, чтобы получить то, что я хочу. Любой другой предложения (если unpack
не спасает день)?
2 ответов
предполагая, что эти ints находятся в порядке big-endian, используйте
#! /usr/bin/perl
use warnings;
use strict;
# for demo only
*ARGV = *DATA;
while (<>) {
my @fields = unpack "x5C2n7",
pack "C*",
map hex, split;
print "[", join("][" => @fields), "]\n";
}
__DATA__
FF FF 09 7D 10 01 07 01 00 02 00 1D 00 00 00 00 00 06 00 07 00
он начинается с упаковки в байтах (C*
) в соответствии с их ценностями. The unpack
шаблон имеет следующие части:
-
x5
пропускает пять байт -
C2
декодирует дваunsigned char
значения -
n7
декодирует семь 16-битных больших целых чисел без знака
выход:
$ ./dump-packets [1][7][256][512][7424][0][0][1536][1792]
Если вы хотите использовать unpack для распакованных данных, вам нужно сначала упаковать его снова. И вам нужно убрать пробелы перед этим.
другими словами,
$line =~ tr/ //d; # remove spaces
$line = pack 'H*', $line; # convert hex to binary
# Now you can use unpack.