У меня есть программа 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 для символа/байт, интервала для целочисленной переменной на 16 битов),
Я первоначально хотел использовать unpack
чисто разделять каждую входную строку на переменные, в которых я нуждался. Однако из-за пространства разграничивают в строке, я не уверен, как обработать его (я могу использовать в качестве шаблона, но затем я мог бы также просто использовать разделение!)
Есть ли изящный способ использовать unpack()
? Я не ведущее устройство Perl, но другой путь к, как я предположил прежде, использовать split
и затем вручную преобразуйте каждое шестнадцатеричное число в байт и затем используйте побитовые обработки и маски для получения то, что я хочу. Любые другие предложения (если unpack
не спасает положение)?
Предполагая, что эти INT находятся в большом энденном порядке, используйте
#! /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 *
) в соответствии с их значениями. Распакованный
шаблон
имеет следующие детали:
x5
пропускает пять байтов C2
Decodes Две unsigned Char
значения N7
декодирует Семь 16-битных больших целых unsigned unsigned вывод:
$ ./dump-packets [1][7][256][512][7424][0][0][1536][1792]
Если вы хотите использовать распаковать на распакованных данных, вам нужно сначала сначала упаковать его. И вам нужно будет удалить пробелы, прежде чем вы это сделать.
Другими словами,
$line =~ tr/ //d; # remove spaces
$line = pack 'H*', $line; # convert hex to binary
# Now you can use unpack.