[英]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.