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

int*_*iha 6 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没有保存一天)?

Gre*_*con 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
Run Code Online (Sandbox Code Playgroud)

它首先C*根据它们的值打包bytes().该unpack模板包含以下部分:

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

输出:

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

  • 或者甚至只是`map hex,split` - 几乎是Haskell! (2认同)
  • 别客气!告诉你的朋友!是的,您的模板对于解压缩小端16位无符号整数是正确的."网络顺序"仅仅是一个约定的名称:正如您所观察到的,多字节`int`s在通过网络传输时不会自动转换为网络顺序. (2认同)