2011-03-01 3 views
4

지난 몇 시간 동안 나를 괴롭 히고있는이 작은 문제가 있습니다.Python Struct Unpack

string = b'-' 
t = struct.pack(">h%ds" % len(string), len(string), string) 
print(t) 

이 팩의 결과는 B이다 '\ x00부터 \ x01-'나는 데 문제는 내가 결과 B '를 압축하는 방법을 알아낼 수 없다는 것입니다

\ x00부터 \ X01 - '그냥'- '예. 앞에서 쓰레기를 치울 수는 있지만 좀 더 복잡해집니다. 나는 그것을 여기에서 단순화하려고 노력했다. 잘만되면 누군가 나를 도울 수 있습니다. :)

+0

어쩌면 나는 완전히 오해하지만, http://docs.python.org/library/struct.html#struct.unpack 사용할 수 있습니다 – ide

답변

5

일반적으로 길이 헤더와 값을 함께 넣으려면 struct.pack을 사용하지 마십시오. 대신, 그냥 struct.pack(">h", len(data)) 할 줄을 통해 (예 : 네트워크 프로토콜) 및 데이터를 보냅니다. 새 바이트 버퍼를 만들 필요가 없습니다.

dataLength, = struct.unpack(">h", t[:2]) 
data = t[2:2+dataLength] 

을하지만, 내가 말한대로 예를 들어 소켓 기반 응용 프로그램이있는 경우, 그것은과 같이 될 것이다 : 당신의 경우

, 당신은 간단하게 할 수

header = receive(2) 
dataLength, = struct.unpack(">h", header) 
data = receive(dataLength) 
-1

방법 정확히 짐을 풀고 있니?

>>> string = b'-' 
>>> format = '>h%ds' % len(string) 
>>> format 
'>h1s' 
>>> struct.calcsize(format) 
3 

unpack(fmt, string)를 들어, len(string)struct.calcsize(fmt) 동일해야합니다. 따라서 압축을 푼 데이터가 단지 '-' 일 수는 없습니다.

그러나 :

>>> t = b'\x00\x01-' 
>>> length, data = struct.unpack(format, t) 
>>> length, data 
(1, '-') 

이제 data를 사용할 수 있습니다. 여기

3
import struct 
string = b'-' 
fmt=">h%ds" % len(string) 

당신은 길이와 문자열 모두 포장되어 있습니다 : 당신이 포장을 풀 때

t = struct.pack(fmt, len(string), string) 
print(repr(t)) 
# '\x00\x01-' 

그래서, 당신은 다시 두 개의 값을 얻을 것으로 기대한다을 즉, 길이와 문자열 :

length,string2=struct.unpack(fmt,t) 
print(repr(string2)) 
# '-' 

일반적으로 문자열이 압축 된 방법을 모르는 경우 데이터를 복구 할 확실한 방법이 없습니다. 에이. 당신은 단지 추측해야 할 것입니다!

당신은 은 문자열의 길이로 구성되어 데이터를 알고 있다면, 다음 문자열 자체는, 당신 은 시행 착오를 시도 할 수 :

import struct 
string = b'-' 
fmt=">h%ds" % len(string) 
t = struct.pack(fmt, len(string), string) 
print(repr(t)) 

for endian in ('>','<'): 
    for fmt,size in (('b',1),('B',1),('h',2),('H',2),('i',4),('I',4), 
        ('l',4),('L',4),('q',8),('Q',8)): 
     fmt=endian+fmt 
     try: 
      length,=struct.unpack(fmt,t[:size]) 
     except struct.error: 
      pass 
     else: 
      fmt=fmt+'{0}s'.format(length) 
      try: 
       length,string2=struct.unpack(fmt,t) 
      except struct.error: 
       pass 
      else: 
       print(fmt,length,string2) 
# ('>h1s', 1, '-') 
# ('>H1s', 1, '-') 

이를 구성 할 수도있을를 그러나 t의 모호한 문자열에는 여러 개의 유효한 언 패킹이있어 서로 string2이됩니다. 나는 잘 모르겠다.

+0

오케이. 문자열의 실제 길이를 모르는 경우 어떻게됩니까? – dbdii407

0

struct 모듈은 고정 된 형식의 데이터 블록 용으로 설계되었습니다.다음과 같은 코드를 사용할 수 있습니다 그러나 :

import struct 
t=b'\x00\x01-' 
(length,)=struct.unpack_from(">h", t) 
(text,)=struct.unpack_from("%ds"%length, t, struct.calcsize(">h")) 
print text 
+0

'struct.calcsize ("> h")'는 다소 장황한 방법으로'2'를 작성합니다 –

1

그냥 data 바이트의 큰 덩어리이고 성공적으로 첫 posn 바이트를 분석했다고 가정 해 봅시다. 이 바이트 청크에 대한 문서에 따르면 다음 항목은 16 비트 부호가 붙은 (예상하지 못했지만 h 형식이라고도 함) bigendian 정수가 앞에 오는 바이트 문자열입니다. 수행 할 작업은 다음과 같습니다.

nbytes, = struct.unpack('>h', data[posn:posn+2] 
posn += 2 
the_string = data[posn:posn+nbytes] 
posn += nbytes 

이제 다음 항목을 준비했습니다.

참고 : 나중에 파이썬 2.5로 제한 코드를 작성하는 경우 unpack_from()