开发者

How can I parse space separated STDIN hex strings unpacked in Perl?

开发者 https://www.devze.com 2022-12-19 00:26 出处:网络
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 a开发者_如何学Pythonm piping the

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 a开发者_如何学Pythonm 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)?


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]


If you want to use unpack on unpacked data, you'll need to pack it again first. And you'll need to remove the spaces before you do that.

In other words,

$line =~ tr/ //d;          # remove spaces
$line = pack 'H*', $line;  # convert hex to binary
# Now you can use unpack.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号