6

ネットワーク経由で受信した 16 バイトの raw パケットを、スペースで区切られた 16 進形式で吐き出す Java プログラムがあります。そのコードを変更したくないので、結果を 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
|--ガベージ-----|c--|c--|int---|int---|int---|int---|int---|int---|int- --|

(cはchar/byte、intは16bit整数変数)

unpack私は当初、各入力行を必要な変数にきれいに分離するために使用したいと考えていました。ただし、文字列にスペース区切りがあるため、それを処理する方法がわかりません (「A」をテンプレートとして使用できますが、分割を使用することもできます!)

エレガントな使い方はありunpack()ますか?私は Perl の達人ではありませんが、前に提案したように、split各 16 進数を手動でバイトに変換し、ビット操作とマスクを使用して必要なものを取得する方法もあります。他に何か提案unpackはありますか?

4

2 に答える 2

8

これらのintがビッグエンディアンの順序であると仮定して、

#! /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テンプレートには次の部分があります。

  • x55バイトスキップします
  • C2unsigned char2つの値をデコードします
  • n77つの16ビットビッグエンディアン符号なし整数をデコードします

出力:

$ ./dump-packets
[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 に答える