0

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 typecastingintVar=(int*)someBasePointer in C


Added after marking as answered:

Is there a way to do this for odd bit structure? Like theCHS. 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}
askedOct 20, 2012 at 18:10
Lord Loh.'s user avatar
1

2 Answers2

4

You want thestruct.unpack() function.

import structdef 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 andh are the signed int versions; if you want unsigned, useI andH)

answeredOct 20, 2012 at 18:16
Amber's user avatar
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. This works! I am looking into the documentation of struct. 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.
struct doesn't support partial bytes, no. You'll still have to do that manipulation yourself.
Thanks. That is useful to know outright than wondering if I am reinventing the wheel.
3

For simple 1-, 2-, or 4-byte fields, your best bet may bestruct.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}
answeredOct 20, 2012 at 18:16
eswald's user avatar

3 Comments

Note that this will return a tuple with one value, not the individual value. Also, silently slicing the input set of bytes isn't going to buy you much andwill mask accidental errors that input more data. It'd be better to just assume you're getting a 4-byte string input.
Thank you. This works! I am looking into the documentation of struct. 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.
@Amber: Good point; I've mostly used unpack for multiple fields, and forgot about that detail.

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.