Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to base64 encode a python array, not double-encode it?

I want to encode an array using base64 in order to transform it into JSON for sending over websocket. I followed the advice of ssubotin in this SO question in my Python code. On the receiving end, in javascript, I use window.atob() to decode the string. Trouble is, I have to use window.atob() twice. This suggests that I somehow double-encoded my data and thus made the string 33% longer than it needed to be. Some output is shown below the code.

# based on https://websockets.readthedocs.io/en/9.0.1/intro.html
import asyncio
import json
from base64 import b64encode, b64decode
import array

myarray = array.array('H', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]) 

class Base64Encoder(json.JSONEncoder):
    # ssubotin, https://stackoverflow.com/questions/37225035/serialize-in-json-a-base64-encoded-data
    def default(self, o):
        if isinstance(o, bytes):
            return b64encode(o).decode()
        return json.JSONEncoder.default(self, o)
        

# array_event() creates a message which will be sent over websocket

def array_event():
    bytextnd = bytearray()
    for x in range(len(myarray)):
        bytextnd.extend(myarray[x].to_bytes(2, byteorder='big'))
    print(format(b64decode(b64encode(bytextnd)))) # gives bytes en/de-coded
    print(json.dumps({"type": "array", "array": b64encode(bytextnd)}, cls=Base64Encoder))
    return json.dumps({"type": "array", "array": b64encode(bytextnd)}, cls=Base64Encoder)

Python output:
b’\x00\x01\x00\x02\x00\x03\x00\x04 […] \x00\x0f\x00\x10′

{"type": "array", "array": "QUFFQUFnQURBQVFBQlFBR0FBY0FDQUFKQUFvQUN3QU1BQTBBRGdBUEFCQT0="}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Javascript yields this as the result of the first window.atob():
AAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABA=
which correctly yields the array after a second window.atob() and some DataView and charCodeAt() magic that I borrowed from Nina Scholz.

>Solution :

your doing too much work …

a = array.array('H',range(1,17))
packed_bytes = struct.pack(f">{len(a)}H",*a)
base64_bytes = base64.b64encode(packed_bytes)
print(base64_bytes)
# b'AAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABA='
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading