1

I have a file with big endian binaries. There are two numeric fields. The first has length 8 and the second length 12. How can I unpack the two numbers?

I am using the Python module struct (https://docs.python.org/2/library/struct.html) and it works for the first field

num1 = struct.unpack('>Q',payload[0:8])

but I don't know how I can unpack the second number. If I treat it as char(12), then I get something like '\x00\xe3AC\x00\x00\x00\x06\x00\x00\x00\x01'.

Thanks.

sundar nataraj
  • 8,524
  • 2
  • 34
  • 46
user1895406
  • 1,383
  • 2
  • 9
  • 10
  • Is it a number stored on 12 bytes? – Wookie88 Jun 27 '14 at 13:15
  • Sorry for the confusion: there are 2 numbers to be unpacked, one has length 8 and the second has length 12. num1 I can unpack as stated above. I am having trouble with the second. I am looking for the first argument, x, of struct.unpack(x,payload[8:20]). – user1895406 Jun 27 '14 at 13:35
  • My bad, I misread the question (and deleted a wrong comment that I enter because of it) Have you tried treating it as three ints?: `struct.unpack('>hhh', payload[8:20])` What do you get if you do that? – Savir Jun 27 '14 at 13:36
  • '>hhh' gives struct.error: unpack requires a string argument of length 6. When i change it to '>hhhhhh', then '\x00\xe3AC\x00\x00\x00\x08\x00\x00\x00\x01' becomes (227, 16707, 0, 8, 0, 1). But I think it should be a single number. – user1895406 Jun 27 '14 at 13:43

1 Answers1

1

I think you should create a new string of bytes for the second number of length 16, fill the last 12 bytes with the string of bytes that hold your number and first 4 ones with zeros.

Then decode the bytestring with unpack with format >QQ, let's say to numHI, numLO variables. Then, you get final number with that: number = numHI * 2^64 + numLO*. AFAIR the integers in Python can be (almost) as large as you wish, so you will have no problems with overflows. That's only rough idea, please comment if you have problems with writing that in actual Python code, I'll then edit my answer to provide more help.

*^ is in this case the math power, so please use math.pow. Alternatively, you can use byte shift: number = numHI << 64 + numLO.

Wookie88
  • 33,079
  • 4
  • 27
  • 32
  • I think that worked! Starting with string='\x00\xe3AC\x00\x00\x00\x08\x00\x00\x00\x01', I created x='0000'+string, then I unpack numHI,numLO= unpack('>QQ',x). Using your formula above, I get number=6944656625227956935. Unfortunately, I cannot check right now if that number is right. – user1895406 Jun 27 '14 at 13:56
  • I'm glad. Also, I have made small edit-you can use byte shift instead of power :) – Wookie88 Jun 27 '14 at 13:58
  • thanks for your help. one thing. `number = numHI * 2^64 + numLO` is a lot faster than `number = numHI << 64 + numLO` – user1895406 Jun 27 '14 at 14:20
  • That's strange, I would say that binary operations are faster :). – Wookie88 Jun 27 '14 at 20:06
  • i agree, in general. though my machine had difficulties with <<64. anyway, the important thing is that i got the number. – user1895406 Jun 27 '14 at 21:54