6

我有一个 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'作为模板,但我还不如只使用拆分!)

有没有优雅的使用方式unpack()?我不是 Perl 大师,但另一种方法是,正如我之前建议的那样,使用split然后手动将每个十六进制转换为一个字节,然后使用位操作和掩码来获得我想要的。任何其他建议(如果unpack不保存一天)?

4

2 回答 2

8

假设这些整数是大端顺序,使用

#! /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 位大端无符号整数

输出:

$ ./转储数据包
[1][7][256][512][7424][0][0][1536][1792]
于 2010-02-01T22:39:30.987 回答
3

如果你想在解压后的数据上使用 unpack,你需要先再次打包。在你这样做之前,你需要删除空格。

换句话说,

$line =~ tr/ //d;          # remove spaces
$line = pack 'H*', $line;  # convert hex to binary
# Now you can use unpack.
于 2010-02-01T22:27:05.477 回答