将base64编码的字节数组解码为(负)十进制值(Java到Python)

时间:2018-02-20 12:51:59

标签: java python

我知道这段代码是用Java编写的:

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

然而,当我尝试在Python中做同样的事情时,我得到一个奇怪的整数值:

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

但是,这个Python代码适用于整数(例如:'DUYl8JO2hi0 ='===> 956493686063400493)。得到正确的十进制值我做错了什么?

编辑:这可能与小数值为负值有关吗?

1 个答案:

答案 0 :(得分:0)

在base64中解码时,('')+给出以下5个字节:0xfd 0xb7 0xdb 0x28 0xd9。在Python中你只需要取数字值0xfdb7db28d9,这实际上是十进制的1089711319257。

但是当设置高位时,BigInteger类将其处理为两位补码表示的负数,比如0xfdb7db28d9 - 0x10000000000 = -9800308519

AFAIK,Python没有相当于Java BigInteger的自动处理负值,所以为了模仿Java处理,你必须控制是否设置了高阶位,如果是,则手动取两个“s”。补充价值。

Python 2代码可能是:

'/bfbKNk='

实际打印

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

如果您更喜欢使用Python 3,代码可能会变成:

-9800308519