Lord Loh.
Lord Loh.

Reputation: 2477

Interpreting binary string as integer in python

I am reading a file (disk images and /dev/sda and likes) in python using binary mode. I am reading the first sector (512 bytes) and am trying to print disk information (ref: Wikipedia Articles).

To interpret things like the 32bit LBA of first absolute sector in the partition, I am doing things like -

def int32(bytes):
    return int(bytes[3]<<24|bytes[2]<<16|bytes[1]<<8|bytes[0])

def int16(bytes):
    return int(bytes[1]<<8|bytes[0])

print('LBA:',int32(partitionEntry[8:12]))

Is there native wat to do this in python? As typecasting intVar=(int*)someBasePointer in C


Added after marking as answered:

Is there a way to do this for odd bit structure? Like the CHS. C (cylinders) are 10 bits 8 bits from one byte and 2 from the other byte. My current approach for this is

def getCHS(bytes):
    c=bytes[1]&3<<8|bytes[2]
    h=bytes[0]
    s=bytes[1]&63
    return {'c':c,'s':s,'h':h}

Upvotes: 0

Views: 1653

Answers (2)

eswald
eswald

Reputation: 8406

For simple 1-, 2-, or 4-byte fields, your best bet may be struct.unpack. Try something like:

def int32(bytes):
    return struct.unpack("i", bytes[:4])[0]

You might need to specify the endian with "<i" or ">i" as the format string.

However, more unusual field widths require masking and/or bitshifting. Your approach works well; alternatively, you could unpack an unsigned type of sufficient size, but it doesn't save much work:

def getCHS(bytes):
    h, r = struct.unpack("BH", bytes[:3])
    c = r & 0x3F
    s = r >> 10
    return {'c':c,'s':s,'h':h}

Upvotes: 3

Amber
Amber

Reputation: 526743

You want the struct.unpack() function.

import struct

def int32(some_bytes):
    return struct.unpack("i", some_bytes)[0]

def int16(some_bytes):
    return struct.unpack("h", some_bytes)[0]

If you're reading from a system that uses different endian values than the current system, you may need to specify the endianness in the format string as well.

(i and h are the signed int versions; if you want unsigned, use I and H)

Upvotes: 4

Related Questions