Base64 Binary String representation to float convertion

Question:

I did a lot of research and can’t seem to find the answer for this, e.g:

link1
link2

So I have this base64 encoded string: BzM=, and I know that the correct value is 18.43

This value comes from a decimal field from a MySql database with the following associated definition {'scale': '2', 'decimal.precision': '8'}, so it’s DECIMAL(8,2).

The implementation in Java:

String encoded = "BzM=";
int scale = 2; // comes from definition above associated with the field
final BigDecimal decoded = new BigDecimal(new BigInteger(Base64.getDecoder().decode(encoded)), scale);
System.out.println("RES: " + decoded); // RES: 18.43

Working example on Ideone

I’m almost sure that there’s an ‘easy’ way for doing this with Python as well, I searched a lot and couldn’t find anything helpful (I may have searched the wrong way).

I tried to reverse engineer this, with no success (can’t find where the scale arg enters also):

import base64, struct
x = base64.encodebytes(struct.pack('!f', 18.43))
print(x) # b'QZNwpA==n' SHOULD BE BzM=

So, I need to simply translate this Java implementation into Python3.

Asked By: Manuel Simões

||

Answers:

You can use base64.b64decode to decode the string, then convert the result byte-string to an int using int.from_bytes, finally dividing by 10**scale to get the required result:

import base64

enc = 'BzM='
bytes = base64.b64decode(enc)
scale = 2
num = int.from_bytes(bytes, byteorder='big') / 10 ** scale
print(num)

Output:

18.43

Out of interest, the reverse coding would be:

base64.b64encode(int.to_bytes(1843, length=int(math.log2(1843))//8+1, byteorder='big'))
Answered By: Nick