10

Pythonで小さなフォーマッターを作成して、16進文字列の行に埋め込まれた数値を返したいと思います。

これは私のフォーマッターの中心的な部分であり、100行/秒以上(各行は約100文字)をフォーマットするのに適度に高速である必要があります。

以下のコードは、私が現在ブロックされている例を示しています。

'data_string_in_orig'は、指定された入力形式を示します。ワードごとにバイトスワップする必要があります。'data_string_in_orig'から'data_string_in_swapped'へのスワップが必要です。最後に、示されているように構造へのアクセスが必要です。期待される結果はコメント内にあります。

よろしくお願いしますWolfgangR

#!/usr/bin/python

import binascii
import struct

## 'uint32 double'
data_string_in_orig    = 'b62e000052e366667a66408d'
data_string_in_swapped = '2eb60000e3526666667a8d40'
print data_string_in_orig

packed_data = binascii.unhexlify(data_string_in_swapped)
s = struct.Struct('<Id')
unpacked_data = s.unpack_from(packed_data, 0)  
print 'Unpacked Values:', unpacked_data

## Unpacked Values: (46638, 943.29999999943209)

exit(0)
4

4 に答える 4

16

array.arraysバイトスワップメソッドがあります:

import binascii
import struct
import array
x = binascii.unhexlify('b62e000052e366667a66408d')
y = array.array('h', x)  
y.byteswap()
s = struct.Struct('<Id')
print(s.unpack_from(y))

# (46638, 943.2999999994321)

hinが選択されたのは、データ inを 2 バイト short の配列と見なすarray.array('h', x)ように指示するためです。重要なことは、各項目が 2 バイト長であると見なされることです。2 バイトの unsigned short を意味する も同様に機能します。array.arrayxH

于 2012-10-31T10:25:32.457 に答える
10

これは unutbu のバージョンとまったく同じように動作するはずですが、一部の人にとっては従うのが少し簡単かもしれません...

from binascii import unhexlify
from struct import pack, unpack
orig = unhexlify('b62e000052e366667a66408d')
swapped = pack('<6h', *unpack('>6h', orig))
print unpack('<Id', swapped)

# (46638, 943.2999999994321)

基本的に、6 shorts ビッグ エンディアンを展開し、6 shorts リトル エンディアンとして再パックします。

繰り返しますが、unutbu のコードと同じことなので、彼のコードを使用する必要があります。

編集これに私のお気に入りのPythonイディオムを使用できることに気づきました...これもしないでください:

orig = 'b62e000052e366667a66408d'
swap =''.join(sum([(c,d,a,b) for a,b,c,d in zip(*[iter(orig)]*4)], ()))
# '2eb60000e3526666667a8d40'
于 2012-10-31T10:43:51.380 に答える
1

「data_string_in_orig」から「data_string_in_swapped」へのスワップは、インポートを使用せずに内包表記で行うこともできます。

>>> d = 'b62e000052e366667a66408d'
>>> "".join([m[2:4]+m[0:2] for m in [d[i:i+4] for i in range(0,len(d),4)]])
'2eb60000e3526666667a8d40'

内包表記は、16 ビット ワードを表す 16 進文字列のバイト順を交換するために機能します。異なるワード長に変更するのは簡単です。一般的な 16 進数の順序スワップ関数も作成できます。

def swap_order(d, wsz=4, gsz=2 ):
    return "".join(["".join([m[i:i+gsz] for i in range(wsz-gsz,-gsz,-gsz)]) for m in [d[i:i+wsz] for i in range(0,len(d),wsz)]])

入力パラメータは次のとおりです。

d : 入力 16 進文字列

wsz: ニブル単位のワード サイズ (例: 16 ビット ワードの場合 wsz=4、32 ビット ワードの場合 wsz=8)

gsz: 一緒にとどまるニブルの数 (たとえば、バイトを並べ替える場合は gsz=2、16 ビット ワードを並べ替える場合は gsz = 4)

于 2016-04-20T12:55:09.453 に答える
0
import binascii, tkinter, array
from tkinter import *

infile_read = filedialog.askopenfilename()

with open(infile, 'rb') as infile_:
    infile_read = infile_.read()

x = (infile_read)
y = array.array('l', x)
y.byteswap()
swapped = (binascii.hexlify(y))

これは、「unutbu」の回答とほぼ同じコードで実現した 32 ビットの符号なしショート スワップで、少しだけ理解しやすくなっています。また、技術的には、スワップに binascii は必要ありません。array.byteswap のみが必要です。

于 2015-05-04T13:38:18.733 に答える