21

I would create a python script that decode a Base64 string to an array of byte (or array of Hex values).

The embedded side of my project is a micro controller that creates a base64 string starting from raw byte. The string contains some no-printable characters (for this reason I choose base64 encoding).

On the Pc side I need to decode the the base64 string and recover the original raw bytes.

My script uses python 2.7 and the base64 library:

base64Packet = raw_input('Base64 stream:')

packet = base64.b64decode(base64Packet )

sys.stdout.write("Decoded packet: %s"%packet)

The resulting string is a characters string that contains some not printable char.

Is there a way to decode base64 string to byte (or hex) values?

Thanks in advance!

Federico
  • 1,117
  • 6
  • 20
  • 37
  • You already *have* that bytestring. What output were you expecting and what do you see? Perhaps you wanted to use `%r` instead when printing? – Martijn Pieters Aug 29 '16 at 15:28
  • @MartijnPieters: After decoding I would have a python list that contain each single byte. – Federico Aug 29 '16 at 15:31
  • 1
    Why do you need that? Do you need to manipulate the bytes? A `str` object is already a sequence, you can address each byte with `packet[index]`, for example, or loop over the string with `for byte in packet:`. – Martijn Pieters Aug 29 '16 at 15:32
  • You can create the list by just using `list(packet)`, producing a list of 1-character (byte) strings. Or perhaps you want to use a `bytearray` object instead, but it isn't clear what you want to do with your data. You haven't given us your use case. – Martijn Pieters Aug 29 '16 at 15:33
  • Yes I need to manipulate specific bytes! For example I want to parse the byte. Can I convert string to list to manipulate the bytes? Thanks – Federico Aug 29 '16 at 15:35
  • Parsing doesn't require any conversion; just use indexing or slicing. The `struct` module for example doesn't need anything else but the string you already have. – Martijn Pieters Aug 29 '16 at 15:37
  • Yes I know, but I prefer to have a list with integer or hex value to debug the script. – Federico Aug 29 '16 at 15:40
  • 1
    Then you want a `bytearray()` instance; just use `bytearray(packet)`. A bytearray is a mutable sequence of integers in the range 0-255, one integer per byte. – Martijn Pieters Aug 29 '16 at 15:42
  • @MartijnPieters: I solved with this code line: packetString = list(bytearray(base64.b64decode(base64Packet))). Thanks! – Federico Aug 29 '16 at 16:04

1 Answers1

18

You can use bytearray for exactly this. Possibly the binascii module and struct can be helpful, too.

import binascii
import struct

binstr=b"thisisunreadablebytes"

encoded=binascii.b2a_base64(binstr)
print encoded
print binascii.a2b_base64(encoded)

ba=bytearray(binstr)
print list(ba)

print binascii.b2a_hex(binstr)
print struct.unpack("21B",binstr)
janbrohl
  • 2,626
  • 1
  • 17
  • 15
  • Thanks! Could you provide an example for the use of bytearray, binascii and struct to solve my problem? I'm not a master of python! – Federico Aug 29 '16 at 15:44
  • added examples - if you can be more specific on what input should become waht i can extend... – janbrohl Aug 29 '16 at 15:58
  • 1
    Thanks for your example! I obtain the list of integer values with this code line: stapacketString = list(bytearray(base64.b64decode(base64Packet))). Is this the correct way? For my scope this works. – Federico Aug 29 '16 at 16:05
  • Looks correct - actually `bytearray`s behave like `list`s (except for printing) so constructing a `list` is only needed for prettier printing. Glad I could help :) – janbrohl Aug 29 '16 at 16:15