5

I wanted to use the base64 Python library to encode a sequence of binary digits into base 64. Would it be possible to do it without converting to a string? If not, what is the best way to do it, assuming that my string of 1/0 digits may not be an integer multiple of 8, it may even be an odd number.

In addition, I have the following question: is it possible to assign a specific binary string to a variable? For example,

x = 0b00010101010
y = 0b1110000  

I want x to hold the three initial zeros, and I would like to be able to concatenate these to to obtain

z = 0b000101010101110000
3
  • This question is probably a better fit for StackOverflow.com; voted to migrate it there. Jul 26, 2012 at 7:34
  • @MartijnPieters - I think this is more of a design question than a coding question and therefore it's fine for us.
    – ChrisF
    Jul 26, 2012 at 7:59
  • @ChrisF: Okidoki; I found it to be borderline, glad it appears to be on-topic anyway :-) Jul 26, 2012 at 8:18

2 Answers 2

3

In Python, the 0b binary representation notation is just another way of writing integers. So there is no difference, for example, between 0b11 and 0b0011 - they both represent the integer 3.

Also, base64 encoding is designed for input data in 8-bit groups. The encoding is designed so that the decoder may determine exactly the number of bytes that were used in the original data. However, this granularity extends only to 8-bit groups and does not extend down to the actual bit level.

One approach might be to encode your data with the first byte representing the number of bits, and then the following bytes representing the actual bits themselves. Your decoder could use this information to extract the exact number of bits you originally stored (with leading or trailing zeros, if you like).

1

Both x and y hold integer values, you just choose to use 0b binary literals to define them.

If you want to combine the two into z, you can easily do so using a shifting operation and binary bitwise operations:

>>> x = 0b00010101010
>>> y = 0b1110000
>>> z = (x << 7) | y
>>> bin(z)
'0b101010101110000'

Do note that python does not track how many bits 'precision' you want to keep on such values; you defined y with 7 bits of information, so I had to shift x to the left 7 times to make room for y. You'd have to track this information yourself.

Your next problem is representing data as base64 as this format requires you to provide it with bytes only. That's chunks of 8 bits of binary data. This means you'll have to align your bits to the 8-bit boundaries and then turn these into bytes (e.g. strings). You won't be able to get around that, I'm afraid.

I'd use the struct module for that, it lets you pack integers and other data-types into bytes with ease:

>>> import struct
>>> struct.pack('>H', x)
'\x00\xaa'
>>> struct.pack('>H', x).encode('base64')
'AKo=\n'

In the above example I've packed the 11-bits x variable as an unsigned short (using the little-endian standard C format), resulting in 2 bytes of information, then encoded that to base64.

The reverse then requires decoding from base64, then an unpack operation:

>>> foo = struct.unpack('>H', 'AKo=\n'.decode('base64'))[0]
>>> bin(foo)
'0b10101010'

Again, Python doesn't track how many bits of information is important to you, you'll have to track that explicitly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.