命令:
echo "HelloWorld==" | base64 -d | base64
输出:
HelloWorlQ==
为什么我的d
现在是一个Q
?
编辑:
我不想从任意数据开始并对其进行 base64 编码。我的意图是从 Base64 开始并以 Base64 结束,在此期间只产生了一个二进制值。
编辑 2:
我注意到如果输入字符串是四个字符的倍数,则不会发生这种情况,所以我认为这是与填充的交互:
❯ echo 'abcdefghij==' | base64 -d | base64
abcdefghig==
❯ echo 'abcdefgh' | base64 -d | base64
abcdefgh
编辑 3
删除了对标志的混淆提及-i
,结果证明这与我的问题无关。
HelloWorld==
包含无法解码的信息,并且在技术上不是有效的 Base64,因为它们通常应该被0
填充。当1
你echo "HelloWorld==" | base64 -d
.解释...
Base64 适用于 4 个字符的组。每个字符代表 6 位,因此每组 4 个解码为 3 个字节(每字节 8 位)。唯一的例外是最后 4 个字符,这将根据
=
符号的数量而有所不同。Base64 字符串总是能被 4 整除。在您的示例中
Hell
,并且oWor
都是有效的。但ld==
不是。要了解为什么要查看此查找表: https ://en.wikipedia.org/wiki/Base64ld==
应该只解码为一个字节,因为它最后有两个=
。但ld
解码为:100101 011101
. 一个字节只有八个 8 位。因此,当您使用 解码字符串时base64 -d
, only100101 01
将被转换为字节,并且结尾1101
将被完全忽略。任何以 64 为结尾的字符串
==
只能使用最后一个字符的前两位。那是唯一有效的结尾==
是Q==
A==
w==
g==
是的,这是与填充的交互。
让我们通过解码来查看您的实际编码数据,并且(因为它不是 ASCII 字符串)将其转换为二进制:
这是
HelloWorld==
base64编码的数据。Philip Couling解释了最终ld==
部分解码的复杂性,并且在某种程度上,d
在解码数据时实际使用了由该部分编码的数据的三分之一。下面我将展示Q
重新编码数据时的来源。让我们重复那个二进制文件:
以六位为一组(这是 base64 编码器将使用的):
这在末尾填充了四个零位,以形成 10 个完整的 6 位代码:
这
010000
是Q
您在重新编码数据时看到的(参见 base64 代码表)。管道不正常。在解码之前,您应该先编码。
您正在解码无效的 base64 编码格式。