java.util.Base64 解码再编码会产生不同的字符串

4
问题:解码Fz+=,然后重新编码会得到Fz8=。
以下是代码:
new String(Base64.getEncoder().encode(Base64.getDecoder().decode("Fz+=".getBytes("UTF-8"))))

给出以下字符串: Fz8= 加号如何变成8?
我一定漏掉了什么。
Fz+= 的位模式为:000101 110011 111110 000000
重新排列成8位组:00010111 00111111 10000000
换算成十进制:23 63 128
这需要3个字节来表示。
然而,当我尝试运行以下代码时:
Base64.getDecoder().decode("Fz+=".getBytes("UTF-8"))

我得到了以下十进制数组:

 [23, 63]

最后一个字节(1000 0000)去哪了?这就是将其编码时+变成8的原因。

1
似乎是由于UTF-8转换导致的往返数据丢失?不是完全确定,但这篇文章可能会有所帮助。看起来与如何将128扩展为多个字节有关。 - ztaylor54
1个回答

4
输入的字符串Fz+=不是有效的Base64编码。
根据定义,如果编码后的字符串以一个填充字符结尾,则产生该编码四元组的输入仅包含两个字节。在编码时,应使用0x00填充两个字节的输入,使其成为完整的3字节单元,然后将其编码为4个Base64代码字节。
无论出现这种情况的原因是什么,输入Fz+=都是无效的,解码器只会忽略掉多余的两个比特。
如果输入确实是00010111 00111111 10000000,则正确的编码是没有填充的Fz+A,而A代码表示000000。这很可能是由于最初进行编码的程序中存在错误导致的。

非常感谢您的回答!我之前并不知道这一点。这是否意味着,例如00010111 00111111 10000000的正确base64编码应该是Fz+A? - user39950
谢谢,是的我发帖后不久就编辑了我的回答。这样很有道理。 - user39950

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接