5

この Perl 文字列の Python アナログが必要です。

unpack("nNccH*", string_val)

nNccH*Python 形式の文字で - データ形式が必要です。

Perl では、バイナリ データを 5 つの変数にアンパックします。

  • 「ネットワーク」の 16 ビット値 (ビッグエンディアン)
  • 「ネットワーク」の 32 ビット値 (ビッグエンディアン)
  • 符号付き char (8 ビット整数) 値
  • 符号付き char (8 ビット整数) 値
  • 16 進文字列、最初に上位ニブル

しかし、私はPythonでそれを行うことはできません

もっと:

bstring = ''
while DataByte = client[0].recv(1):
    bstring += DataByte
print len(bstring)
if len(bstring):
    a, b, c, d, e = unpack("nNccH*", bstring)

Perl や Python で書いたことはありませんが、現在の仕事は、Perl で書かれたマルチスレッドの Python サーバーを作成することです...

4

2 に答える 2

8

Perl 形式"nNcc"は Python 形式と同等です"!HLbb"。Python には、Perl の に直接相当するものはありません"H*"

2 つの問題があります。

  • Pythonstruct.unpackはワイルドカード文字を受け入れません。*
  • Pythonstruct.unpackはデータ文字列を「hexlify」しません

最初の問題は、 のようなヘルパー関数を使用して回避できますunpack

2 番目の問題は、次を使用して解決できますbinascii.hexlify

import struct
import binascii

def unpack(fmt, data):
    """
    Return struct.unpack(fmt, data) with the optional single * in fmt replaced with
    the appropriate number, given the length of data.
    """
    # http://stackoverflow.com/a/7867892/190597
    try:
        return struct.unpack(fmt, data)
    except struct.error:
        flen = struct.calcsize(fmt.replace('*', ''))
        alen = len(data)
        idx = fmt.find('*')
        before_char = fmt[idx-1]
        n = (alen-flen)//struct.calcsize(before_char)+1
        fmt = ''.join((fmt[:idx-1], str(n), before_char, fmt[idx+1:]))
        return struct.unpack(fmt, data)

data = open('data').read()
x = list(unpack("!HLbbs*", data))
# x[-1].encode('hex') works in Python 2, but not in Python 3
x[-1] = binascii.hexlify(x[-1])
print(x)

この Perl スクリプトによって生成されたデータでテストすると、次のようになります。

$line = pack("nNccH*", 1, 2, 10, 4, '1fba');
print "$line";

Pythonスクリプトは

[1, 2, 10, 4, '1fba']
于 2012-02-07T13:31:42.230 に答える
7

あなたが探している同等のPython関数はですstruct.unpack。フォーマット文字列のドキュメントはここにあります:http://docs.python.org/library/struct.html

必要な開梱の種類を実際に説明すると、助けを得る可能性が高くなります。誰もがPerlを知っているわけではありません。

于 2012-02-07T12:37:42.033 に答える