Question

I want to read bytes 1,2 and 3 from a file. I know it corresponds to a string (in this case it's ELF of a Linux binary header)

Following examples I could find on the net I came up with this:

with open('hello', 'rb') as f:
    f.seek(1)
    bytes = f.read(3)
    string = struct.unpack('s', bytes)
    print st

Looking at the official documentation of struct it seems that passing s as argument should allow me to read a string.

I get the error:

st = struct.unpack('s', bytes)
struct.error: unpack requires a string argument of length 1

EDIT: Using Python 2.7

Was it helpful?

Solution

In your special case, it is enough to just check

if bytes == 'ELF':

to test all three bytes in one step to be the three characters E, L and F.

But also if you want to check the numerical values, you do not need to unpack anything here. Just use ord(bytes[i]) (with i in 0, 1, 2) to get the byte values of the three bytes.

Alternatively you can use

byte_values = struct.unpack('bbb', bytes)

to get a tuple of the three bytes. You can also unpack that tuple on the fly in case the bytes have nameable semantics like this:

width, height, depth = struct.unpack('bbb', bytes)

Use 'BBB' instead of 'bbb' in case your byte values shall be unsigned.

OTHER TIPS

In Python 2, read returns a string; in the sense "string of bytes". To get a single byte, use bytes[i], it will return another string but with a single byte. If you need the numeric value of a byte, use ord: ord(bytes[i]). Finally, to get numeric values for all bytes use map(ord, bytes).

In [4]: s = "foo"

In [5]: s[0]
Out[5]: 'f'

In [6]: ord(s[0])
Out[6]: 102

In [7]: map(ord, s)
Out[7]: [102, 111, 111]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top