waylonion
waylonion

Reputation: 6976

Python treat String as array of bits

I am parsing a file in Python by reading in a chunk of data at a time. Using struct.unpack, I can parse the chunk of data into integer, string, and other typed components.

The structure of the data is 64 bits of binary data and 64 bits of padding.

For instance

res = struct.unpack('>64s64x', s)

With this, I can unpack the struct into a 64 bit long "string" with 64 bits of padding.

My main goal is to take that 64 bit "string", res[0], and invert it. (switch the 1s to 0s and vice versa)

However, how do I cast this string to a bit array and process it?

Note - also printing res[0] gives a bunch of gibberish, not 1s and 0s, since the "string" itself is not a string representation of the binary data. The bit array is being treated as a string...

Upvotes: 0

Views: 465

Answers (1)

kitti
kitti

Reputation: 14834

Specifically it's being interpreted as bytes (which is the same as str in Python 2, but not 3). If your goal is just to invert the bits of the data, that's fairly easy, you can use ord() to get the int value of the character, then use bitwise-xor with 0xff to invert (I'll use a simple string of characters just as an example string):

>>> data = 'abcdefgh'
>>> [ord(x) for x in data]
[97, 98, 99, 100, 101, 102, 103, 104]
>>> [ord(x) ^ 0xff for x in data]
[158, 157, 156, 155, 154, 153, 152, 151]

And if you need to pass that data back to somewhere as bytes:

result = ''.join(chr(ord(x) ^ 0xff) for x in data)

If you want to check the value of individual bits, you can do this with bit masking (which is the standard way of doing this, even in C):

>>> bool(ord('a') & 0x01)
True
>>> bool(ord('a') & 0x02)
False
>>> bool(ord('a') & 0x04)
False
>>> bool(ord('a') & 0x08)
False
>>> bool(ord('a') & 0x10)
False
>>> bool(ord('a') & 0x20)
True
>>> bool(ord('a') & 0x40)
True
>>> bool(ord('a') & 0x80)
False

Upvotes: 3

Related Questions