How can I parse space separated STDIN hex strings unpacked in Perl?
parsing, perl, unpack
Solution
Assuming those ints are in big-endian order, use
#! /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
It starts off by packing in the bytes (`C*`) according to their values. The `unpack` template has the following parts:
- `x5` skips five bytes
- `C2` decodes two `unsigned char` values
- `n7` decodes seven 16-bit big-endian unsigned integers
Output:
$ ./dump-packets
[1][7][256][512][7424][0][0][1536][1792]
Problem
I have a Java program that spits out, in space-separated hexadecimal format, 16 bytes of raw packet received over the network. Since I dont want to change that code, I am piping the result to a Perl script that, theoretically, can simply `unpack` this from `STDIN` into recognizable variables. The following is a sample of the line input to my Perl file: ``` 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 is for char/byte, int for 16bit integer variable) I initially wanted to use `unpack` to cleanly separate each input line into variables that I needed. However, because of the space delimit in the string, I am not sure how to handle it (I can use 'A' as a template, but then I might as well just use split!) Is there a elegant way of using `unpack()`? I am not a Perl master, but the other way is to, as I suggested before, use `split` and then manually convert each hex to a byte, and then use bit manipulations and masks to get what I want. Any other suggestions (if `unpack` doesnt save the day)?