首页 > 解决方案 > 是否有可能与 base64 编码/解码发生冲突

问题描述

这里问了一个类似的问题:Base64 encoding always one to one

显然答案(对类似问题)是肯定的。我已经知道了,但是我很想知道为什么这两个字符串在经过 Base64 解码后看起来是等价的:

cwB0AGQAAG==

cwB0AGQAAA==


还有一件事......当您选择解码后的字符串然后重新编码时,两者都重新编码为相同的值:cwB0AGQAAA==

发生了什么?

标签: encodingbase64

解决方案


base64 不是一对一的;有多种方法可以对相同的字节进行编码。您所看到的是在字符串末尾对填充进行编码的多种方法。

base64 将字节(每个 8 位)编码为 base 64。base64 中的字符编码 6 位,因此四个 base64 字符可以处理三个字节。当输入的长度不是三个字节的倍数时,base64=用作填充字符来填充最后一组四个 base64 字符。XXX=表示仅使用组的前两个字节(其中XXX表示三个任意 base64 字符),而XX==表示仅应使用第一个字节。

您示例中的最后一组是AA==,它编码一个 0 字节。但是,该AA部分可以编码 12 位,其中最低有效 4 位在解码时被忽略,因此您可以使用任何字符A-P并获得相同的结果。当你使用编码器时,它总是为这四个位选择零,所以你回来了AA==

填充实际上在 base64 中更加复杂。从技术上讲,您可以排除=字符;字符串的长度将表明它们不存在(根据维基百科,并非所有解码器都支持这一点)。填充有用的地方在于它允许安全地连接 base64 字符串,因为每组四个字符串都以相同的方式解释。但是,这意味着填充也可以出现在字符串的中间,这意味着可以以各种方式对字节序列进行编码。您还可以包含空格或换行符,它们都会被忽略。

尽管如此,base64 仍然是单射的,这意味着如果 x != y,则 base64(x) != base64(y); 因此,您不会发生冲突,并且始终可以取回原始数据。然而,base64 并不是满射的:有很多方法可以对相同的数据进行编码。


推荐阅读