有谁知道为什么会发生这种情况以及如何解决它?
me@box:~$ echo "eyJmb28iOiJiYXIiLCJiYXoiOiJiYXQifQ" | base64 -di
{"foo":"bar","baz":"bat"}base64: invalid input
答案1
如果您执行相反的操作,您会注意到该字符串不完整:
$ echo '{"foo":"bar","baz":"bat"}' | base64
eyJmb28iOiJiYXIiLCJiYXoiOiJiYXQifQo=
$ echo "eyJmb28iOiJiYXIiLCJiYXoiOiJiYXQifQo=" | base64 -di
{"foo":"bar","baz":"bat"}
摘录如果输入长度不能被3整除,为什么base64编码需要填充?
什么是填充字符?
填充字符有助于满足长度要求,但没有任何意义。
然而,在 Base64 编码的字符串以单个序列的长度丢失的方式连接的情况下,填充非常有用,例如在非常简单的网络协议中可能会发生这种情况。
如果连接未填充的字符串,则无法恢复原始数据,因为有关每个单独序列末尾的奇数字节数的信息会丢失。然而,如果使用填充序列,则不会有歧义,并且整个序列可以被正确解码。
答案2
命令行工具对适当数量的填充字符很挑剔,以使输入长度成为四的倍数。该字符串有 34 个字符长,因此=
末尾应该有两个符号作为填充。
$ echo "eyJmb28iOiJiYXIiLCJiYXoiOiJiYXQifQ==" | base64 -di; echo
{"foo":"bar","baz":"bat"}
如果输入缺少填充字符,则结果因实现而异。正确的 Base64 编码abcd
是YWJjZA==
:
% echo -n abcd |base64
YWJjZA==
如果我们尝试在删除填充字符的情况下对其进行解码,最后一部分就会得到默默地落下在苹果机上:
% echo 'YWJjZA' |base64 -d
abc
虽然使用 GNU 实现,完整的输出就在那里,但我们收到一条错误消息(到 stderr):
$ echo 'YWJjZA' |base64 -d
abcdbase64: invalid input
答案3
GNUbase64 -d
需要适当的填充(输入长度必须是 4 的倍数)。其他base64
解码器可能更智能并且不需要填充(例如Mac/BSDbase64 -D
不需要填充)。
这是一个可以自动正确填充字符串的 bash 命令base64
。这样您就不会收到“无效输入”错误。
str="eyJmb28iOiJiYXIiLCJiYXoiOiJiYXQifQ"
echo "$str"==== | fold -w 4 | sed '$ d' | tr -d '\n' | base64 --decode
解释:
echo "$str"====
添加 4 个等号fold -w 4
将每 4 个字符分成单独的行sed '$ d'
删除最后一行(无关的填充)tr -d '\n'
连接所有行