Richard
Richard

Reputation: 69

How to Convert Binary String to Byte-like Object in Python 3?

I have this line in my program: TextV = base64.b64decode('0cQ+bNsObaw=') and the value of TextV is b'\xd1\xc4>l\xdb\x0em\xac'. Then I run this to convert TextV to binary:

TextVBin = ''.join(format(x, 'b') for x in bytearray(TextV))

and the value of TextVBin is '11010001110001001111101101100110110111110110110110101100'. Now, I wanna again convert TextVBin format to TextV format(i.e. b'\xd1\xc4>l\xdb\x0em\xac') But I googled and I couldn't find any answer. How can I do this in Python 3?

Upvotes: 0

Views: 5880

Answers (2)

Guillaume
Guillaume

Reputation: 6009

I would use:

import struct
TextVBin = "{:b}".format(struct.unpack(">Q", TextV)[0])

to convert your TextV to binary string.

It however produces 1101000111000100001111100110110011011011000011100110110110101100 which is different than your own output, but I guess that is because leading 0 are truncated for each byte with your own method. So your method is wrong.

using struct: 1101000111000100001111100110110011011011000011100110110110101100

using yours: 1101000111000100 111110 110110011011011 1110 110110110101100

Then to convert this binary string back to bytes:

int('1101000111000100001111100110110011011011000011100110110110101100', 2).to_bytes(8, 'big')

Note: I assumed that your TextVBin is 8 bytes long and big endian based on your example. If length is variable, my answer does not apply.

Upvotes: 2

nneonneo
nneonneo

Reputation: 179422

The problem is that your format string truncates leading zeros. You should use

TextVBin = ''.join('{:08b}'.format(x) for x in bytearray(TextV))

which will format each byte with exactly 8 binary digits. Then, to reverse, simply do

TextV = bytearray([int(TextVBin[i:i+8], 2) for i in range(0, len(TextVBin), 8)])

For example:

>>> import base64
>>> TextV = base64.b64decode('0cQ+bNsObaw=')
>>> TextV
b'\xd1\xc4>l\xdb\x0em\xac'
>>> TextVBin = ''.join('{:08b}'.format(x) for x in bytearray(TextV))
>>> TextVBin
'1101000111000100001111100110110011011011000011100110110110101100'
>>> TextV = bytearray([int(TextVBin[i:i+8], 2) for i in range(0, len(TextVBin), 8)])
>>> TextV
bytearray(b'\xd1\xc4>l\xdb\x0em\xac')

Upvotes: 0

Related Questions