繁体   English   中英

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

[英]Decode base64 encoded byte array to (negative) decimal value (Java to 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)。 获得正确的十进制值我做错了什么?

编辑:这可能与十进制值为负有关?

在 base64 中解码时, '/bfbKNk='给出以下 5 个字节:0xfd 0xb7 0xdb 0x28 0xd9。 在 Python 中,您只需取 0xfdb7db28d9 的数值,它实际上是十进制的 1089711319257。

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

AFAIK,Python 没有用于自动处理负值的 Java BigInteger 的等价物,因此要模拟 Java 处理,您必须控制是否设置了高位,如果设置了,则手动取两个补码值。

Python 2 代码可能是:

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

实际上打印

-9800308519

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

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM