简体   繁体   English

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

[英]Decode base64 encoded byte array to (negative) decimal value (Java to Python)

I know this code is working in Java:我知道这段代码在 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:但是,当我尝试在 Python 中做同样的事情时,我得到了一个奇怪的整数值:

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 (eg: 'DUYl8JO2hi0=' ===> 956493686063400493).但是,此 Python 代码适用于整数(例如:'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?编辑:这可能与十进制值为负有关?

When decoded in base64, '/bfbKNk=' gives the following 5 bytes: 0xfd 0xb7 0xdb 0x28 0xd9.在 base64 中解码时, '/bfbKNk='给出以下 5 个字节:0xfd 0xb7 0xdb 0x28 0xd9。 In Python you just take the numeric value of 0xfdb7db28d9, which is indeed 1089711319257 in decimal.在 Python 中,您只需取 0xfdb7db28d9 的数值,它实际上是十进制的 1089711319257。

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但是当设置高位时,BigInteger 类将其作为二进制补码表示法中的负数处理,比如 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. AFAIK,Python 没有用于自动处理负值的 Java BigInteger 的等价物,因此要模拟 Java 处理,您必须控制是否设置了高位,如果设置了,则手动取两个补码值。

Python 2 code could be: 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

which actually prints实际上打印

-9800308519

If you prefer to use Python 3, code could become:如果您更喜欢使用 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