1

I know this code is working in Java:

new BigDecimal(new BigInteger(Base64.getDecoder().decode('/bfbKNk=')), 2)
===> -98003085.19

However, when I try to do the same thing in Python I get a strange integer value:

from base64 import decodestring
coded_string = "/bfbKNk="
print(float("".join("{0:08b}".format(ord(c)) for c in decodestring(coded_string))))
===> 1089711319257

However, this Python code works for whole numbers (e.g.: 'DUYl8JO2hi0=' ===> 956493686063400493). What am I doing wrong to get the correct decimal value?

EDIT: This could have something to do with the decimal value being negative?

1 Answer 1

2

When decoded in base64, '/bfbKNk=' gives the following 5 bytes: 0xfd 0xb7 0xdb 0x28 0xd9. In Python you just take the numeric value of 0xfdb7db28d9, which is indeed 1089711319257 in decimal.

But as the high order bit is set, the BigInteger class processes it as a negative number in two's-complement notation, say 0xfdb7db28d9 - 0x10000000000 = -9800308519

AFAIK, Python has no equivalent of Java BigInteger for automatic processing of negative value, so to mimic Java processing, you will have to control whether the high order bit is set and if it is, manually take the two's complement value.

Python 2 code could be:

coded_string = "/bfbKNk="
bytes_val = base64.decodestring(coded_string)
bval = "".join("{0:08b}".format(ord(c)) for c in bytes_val)
intval = int(bval, 2)
if ord(bytes_val[0]) & 0x70 != 0:      # manually takes the two's complement
    intval -= int('1' + '00' * len(bytes_val), 16)
print intval

which actually prints

-9800308519

If you prefer to use Python 3, code could become:

coded_string = "/bfbKNk="
bytes_val = base64.decodesbytes(coded_string.encode())
bval = "".join("{0:08b}".format(c) for c in bytes_val)
intval = int(bval, 2)
if bytes_val[0] & 0x70 != 0:           # manually takes the two's complement
    intval -= int('1' + '00' * len(bytes_val), 16)
print(intval)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.