如何解析在Perl中解压缩的空格分隔的STDIN十六进制字符串?

时间:2010-02-01 22:00:59

标签: perl parsing unpack

我有一个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然后手动将每个十六进制转换为一个字节,然后使用位操作和掩码来获得我想要的东西。任何其他建议(如果unpack没有保存当天)?

2 个答案:

答案 0 :(得分:8)

假设这些int是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*)。 unpack模板包含以下部分:

  • x5跳过五个字节
  • C2解码了两个unsigned char
  • n7解码七个16位大端无符号整数

输出:

$ ./dump-packets
[1][7][256][512][7424][0][0][1536][1792]

答案 1 :(得分:3)

如果要在解压缩数据上使用解包,则需要先将其打包。在你这样做之前,你需要删除空格。

换句话说,

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