2012-08-23 3 views
2

파이썬에서 조작해야하는 하드웨어 구조를 나타내는 데이터 세트가 있습니다.크기가 다른 데이터를 부호없는 int 목록으로 패킹

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의 목록에이 구조를 포장 된 아이디어는, 다른 떨어져 목록을 통과 : 진짜 구조의 크기는 4 KB입니다 ... 난 그냥 간단한 예를 채찍 것이다 함수이고, 인 경우 함수는 전체 셰 배너를 메모리에 씁니다. 메모리 쓰기 기능은 한 번에 64 바이트를 수용하므로 두 번 호출해야합니다. 위의 예는, 나는이 통화를 할 필요 했어에 대한

그래서 (내가 쉽게 읽을 수 있도록 큰 엔디안을 사용합니다) :

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])  

문제는 내가이 팩을하는 방법을 모르는 것입니다 모든 종류의 효율적인 방식으로 데이터를 전송할 수 있습니다. structarray을 사용하는 데 어려움을 겪었지만 개념적으로 뭔가 빠졌거나 작업에 잘못된 도구를 사용하고 있습니다.

궁극적으로 데이터 유형을 확인하고, 시프 팅 및 마스킹을 수행하고, ASCII를 16 진수로 변환하고, 필요한 데이터 패킷을 구성하는 커다란 털이 기능을 작성할 수 있음을 알고 있습니다. 그러나 그것은 ... 우아하지 않은 것 같습니다.

파이썬에게 "이것은 2 바이트 길이의 숫자입니다 .2 바이트 숫자를 추가하고 마지막 두 숫자에 추가하십시오."이제는 20 바이트의 문자열입니다. 우리가 만든 64 바이트의 목록을 16 개의 부호없는 정수로 변환한다

packunpack 함수는 내가 사용해야하는 것으로 보인다. 하지만 위에서 말한 것처럼 ... 나는 뭔가를 놓쳤을 것입니다. pack은 어떻게 3 바이트 숫자를 처리합니까? HB과 같은 형식 문자열을 사용하는 경우 pack은 두 개의 인수를 기대합니다 :

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

그리고 unpack은 문자열이 아니고 숫자이기 때문에 사용할 수 없습니다.

희망 문제를 분명히했습니다. 어떤 도움을 많이 주시면 감사하겠습니다!

답변

2

올바른 도구를 사용하고 있지만 팩에 2 개의 인수를 인코딩하지만 하나만 전달한다고 말했습니다.

문자열 HB은 두 개의 값을 묶습니다. 하나는 부호없는 short로, 다른 하나는 부호없는 바이트로 묶습니다. 두 개의 값을 전달하면 작동합니다 :

>>> 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!!!' 
+0

나는이 점을 생각했지만 여기에도 몇 가지 문제가 있다고 생각합니다. 예를 들어, 이는 엔디안에 대한 가정을 만듭니다. –

+1

@AxelAguado : 이미 업데이트 중, 인내 :-) –

+0

[endianness]를 정의 할 수 있습니다 (http://docs.python.org/library/struct.html#byte-order-size-and-alignment) – SeanC

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) 
+0

OP는 서명되지 않은 int를 요청합니다. –

관련 문제