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特性导致的不等串解码相同的主要内容,如果未能解决你的问题,请参考以下文章
Java如何进行Base64的编码(Encode)与解码(Decode)?