【问题标题】:How can I parse space separated STDIN hex strings unpacked in Perl?如何解析在 Perl 中解压缩的空格分隔的 STDIN 十六进制字符串?
【发布时间】:2011-01-11 22:19:57
【问题描述】:

我有一个 Java 程序,它以空格分隔的十六进制格式吐出通过网络接收到的 16 个字节的原始数据包。由于我不想更改该代码,因此我将结果传送到 Perl 脚本,理论上,该脚本可以简单地将 unpackSTDIN 转换为可识别的变量。以下是我的 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 不能挽救这一天)?

【问题讨论】:

    标签: perl parsing unpack


    【解决方案1】:

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

    #! /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]

    【讨论】:

    • 你可以说map { hex } split让它看起来更漂亮:)
    • 或者甚至只是 map hex, split — 几乎是 Haskell!
    • 实际上我确认字节是小端的。奇怪的是,因为它们是通过网络发送的,我原以为应该是按网络顺序发送的。哦,好吧,唯一的改变就是解压“x5C2n7”来解压“x5C2v7”,对吧?并感谢您的回复...这个论坛很棒
    • 不客气!告诉你的朋友!是的,您的模板对于解压缩 little-endian 16 位无符号整数是正确的。 “网络顺序”只是约定的名称:正如您所观察到的,多字节 ints 在通过网络传输时不会自动转换为网络顺序。
    【解决方案2】:

    如果您想对解压后的数据使用 unpack,您需要先再次打包。而且您需要先删除空格。

    换句话说,

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

    【讨论】:

    • 我实际上使用了这个解决方案,因为它看起来更干净(我理解代码在做什么)以及上面建议的解包。如果 java 代码吐出错误字符串,我也可以解析 $line。
    猜你喜欢
    • 2020-11-11
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 2016-11-01
    • 2010-09-17
    • 1970-01-01
    • 2010-12-31
    • 2012-07-31
    相关资源
    最近更新 更多