base64特性导致的不等串解码相同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了base64特性导致的不等串解码相同相关的知识,希望对你有一定的参考价值。

参考技术A base64 是将原串以三个字符一组,转化成24个二进制位再分成四个字符的编码方式。

下图就是将 Man 字符转为 TWFu 的过程。

在很多时候,其实原字串的长度都不是3的倍数,这时候转出来的二进制位长度必然不是24的整数倍。这时候就需要对二进制位进行补零操作。在6个二进制位都为零的时候,base64中就呈现 = 号。

例如
只有 M 字符时,转出来的编码为 TQ== 。

只有 Ma 字符时,转出来的编码为 TWE= 。

以上是编码规则,解码也是类似的,因为在编码的时候,已经严格的让字符串长度保持在4n。所以只需要将4个字符组成一组,再生成3个字符就可以完成解码了。

但值得注意的是,上面所说的6个二进制位都为零呈现 = 号, 是指全部6个0都是补的时候 ,才成立的,在base64对照表中, 0对应A 也是其中的编码规则之一。

如何理解 全部6个0都是补的

当转码时,只有字符 L 时,转出来的编码为 TA== ,而非 T=== ,是因为在A的前两个二进制 0 中,是由 L 提供的。所以这就是base64为什么不可能编出三个 = 号结尾的字串的原因。

再看一个例子,如何理解文章标题 不等串解码相同 ,举一例:

当然 M 的base64编码结果不可能是 TR== ,但 TR== 的解码确实就是 M ,这里不相信以上结果的同学,可以去尝试一下将 TQ== 与 TR== 进行base64解码,会发现得出的结果都是 M 。

原因就出在补 = 号的前置条件 全部6个零都是补的 ,在 TR== 的二进制中,在转化24位二进制时,只有前8位是生效的,而 R 和 Q 的不同位在12位,若要使 TR 成立,则 TR 后必不能跟 = 号,得出字符串应该是 TRA= 。

在 MinGW 上解码 base64 编码的随机数不起作用

【中文标题】在 MinGW 上解码 base64 编码的随机数不起作用【英文标题】:Decoding a base64 encoded random on MinGW not working 【发布时间】:2020-02-28 17:21:43 【问题描述】:

我正在尝试在 MinGW 上制作一个 bash 脚本,但似乎 shell 无法解码如下内容。

t=$(openssl rand -base64 64)
echo "$t" | base64 --decode

导致,

 Ԋ7▒%
     ▒7▒SUfX▒L:o<x▒▒䈏ţ94V▒▒▒▒uW;▒▒pxu▒base64: invalid input

有趣的是,如果我输出 base64 字符并这样运行命令,它就可以工作。

echo "+e5dcWsijZ83uR2cuKxIDJTTiwTvqB7J0EJ63paJdzGomQxw9BhfPvFTkdKP9I1o
g29pZKjUfDO8/SUNt+idWQ==" | base64 --decode

有人知道我做错了什么吗?

谢谢

【问题讨论】:

【参考方案1】:

我通过将--ignore-garbage 标志传递给base64 解码解决了上述情况。它会忽略非字母字符。

echo "$t" | base64 --decode --ignore-garbage

但是,我仍然想知道我是如何创建“垃圾”的;)?

【讨论】:

【参考方案2】:

我认为这里发生的事情是 base64 字符串包含一些嵌入的空格,这会导致实际的“无效输入”w(以及您观察到的垃圾。)

openssl rand -base64 64 命令引入了一些换行符(不是空格),例如,

openssl rand -base64 64 > b64.txt

...然后在编辑器中查看 b64.txt 文件,我看到两条单独的行

tPKqKPbH5LkGu13KR6zDdJOBpUGD4pAqS6wKGS32EOyJaK0AmTG4da3fDuOI4T+k
abInqlQcH5k7k9ZVEzv8FA==

...这意味着'k'和'a'之间有一个换行符

所以 base64 字符串有这个嵌入的换行符。 base64 -d 可以处理换行符(如您的成功示例所示),但它不能处理空格字符。

shell 的某些操作可以将换行符转换为空格。 echo $t 即很可能发生这种情况。如果 t 里面有换行符,那么 echo 将用单个空格替换 then。实际上,它的行为方式可能取决于 shell 选项和应用的字符串引号类型(如果有)。

要修复该命令,我们可以在传递给base64 -d 命令之前删除换行符。

一种方法是使用tr 命令,例如以下适用于 Linux:

t=$(openssl rand -base64 64 | tr -d '\n')
echo $t | base64 -d

... 或者,删除空格,再次使用tr

t=$(openssl rand -base64 64)
echo $t | tr -d ' ' | base64 -d

【讨论】:

我明白了。但是当我执行 `echo "......" | base64 --decode" 也是? @Starx ...你说得对,我澄清了答案,以突出换行符和空格字符的区别 感谢您的更新,但我仍然在 MinGW 上得到相同的输出。

以上是关于base64特性导致的不等串解码相同的主要内容,如果未能解决你的问题,请参考以下文章

关于Base64解码的问题:

Java Base64 编码解码方案总结

Java如何进行Base64的编码(Encode)与解码(Decode)?

Java Base64 加密/解密

Python数据对象的编码和解码,json和pickle模块,base64模块的简单使用

base64无法解码pb+