2

Python で操作する必要があるハードウェア構造を表す一連のデータがあります。実際の構造のサイズは 4 KB です...簡単な例を作成します。

Byte(s)  Value  
0-1      0x0102
2-3      0x0304
4-23     "AStrWith20Characters"
24-63    "WoahThisStringHas40CharactersItIsHuge!!!"
64-71    "Only8Chr"
72-74    0x050607
74       0x08
75-127   0x00 (padding)

アイデアは、この構造を 32 ビット Int のリストにパックし、そのリストを別の関数に渡し、その関数がシバン全体をメモリに書き出すというものです。メモリ書き込み関数は一度に 64 バイトを受け入れるので、2 回呼び出す必要があります。

したがって、上記の例では、次の呼び出しを行う必要があります (読みやすくするためにビッグ エンディアンを使用します)。

WrToMemory([0x01020304, 0x41537472, 0x57697468, 0x3230436, 
            0x61726163, 0x74657273, 0x576F6168, 0x5468697, 
            0x53747269, 0x6E674861, 0x73343043, 0x6861726, 
            0x63746572, 0x73497449, 0x73487567, 0x65212121])

WrToMemory([0x4F6E6C79, 0x38436872, 0x05060708, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000,  
            0x00000000, 0x00000000, 0x00000000, 0x00000000])    

問題は、このデータを効率的な方法でパックする方法がわからないことです。structと の使用に苦労していarrayますが、概念的に何かが欠けているか、仕事に間違ったツールを使用しているだけです。

最終的には、データ型をチェックし、一連のシフトとマスキングを行い、ASCII を 16 進数に変換し、必要なデータ パケットを構成する、大きな毛むくじゃらの関数を記述できることを知っています。しかし、それは...エレガントではないようです。

Pythonに「これは2バイトの長さの数値です。まとめてください。別の2バイトの数値を最後の数値に追加します。これは20バイトの文字列です。追加します. 64 バイトになるまで続けてから、作成したばかりの 64 バイトのリストを 16 個の符号なし整数の lsit に変換します。

pack関数と関数を使用する必要があるようunpackですが、上で述べたように...何か不足しているに違いありません。packたとえば、3バイトの数値をどのように処理しますか? のようなフォーマット文字列を使用する場合HB、次のpack2 つの引数が必要です。

>>> pack('HB', 0x050607)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: pack requires exactly 2 arguments

unpackまた、 は数値ではなく文字列を想定しているため、使用できません。

問題が明確になったことを願っています。どんな助けでも大歓迎です!

4

2 に答える 2

2

適切なツールを使用していますが、packに2つの引数をエンコードするように指示しましたが、1つだけを渡します。

文字列のHB意味:2つの値をパックします。1つは符号なしショートとして、もう1つは符号なしバイトとしてパックします。2つの値を渡すと、次のように機能します。

>>> pack('HB', 0x0506, 0x07)
'\x06\x05\x07'

実験を続けるだけで、コツをつかむことができます。例の最初の値のセットをビッグエンディアン表記で示します。

>>> pack('>2H20c40c', 0x0102, 0x0304)
'\x01\x02\x03\x04AStrWith20CharactersWoahThisStringHas40CharactersItIsHuge!!!'

開始時の「>」に注意してください。これはエンディアンを示します。文字列はシーケンスに変換され、個々の変数として適用されます。一般的には、それらを追加する方が簡単です。

>>> pack('>2H20c40c', 0x0102, 0x0304) + "AStrWith20Characters" + "WoahThisStringHas40CharactersItIsHuge!!!"
'\x01\x02\x03\x04AStrWith20CharactersWoahThisStringHas40CharactersItIsHuge!!!'
于 2012-08-23T20:07:28.897 に答える
0

pack構造体形式を使用してすべてを実行し、たとえば32ビットワード形式を使用して解凍できます。

>>> format="cchi"
>>> p=pack(format,"a","b",1,2)
>>> p
'ab\x01\x00\x02\x00\x00\x00'
>>> (z1,z2)=unpack("ii",p)
>>> (z1,z2)
(90721, 2)
于 2012-08-23T20:16:49.417 に答える