java.util.Base64.getMimeDecoder() 接受超过 76 个字符的字符串是否正常?

Is it normal that java.util.Base64.getMimeDecoder() accepts String longer than 76 characters?

我使用 java.util.Base64(在 Java8 中介绍)及其 rfc2045 解码器可用于 Base64.getMimeDecoder()。我预计长度超过 76 个字符的 Base64 编码字符串的解码会导致异常,但它似乎有效。

String value = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
// encode with rfc4648 to have a String longer than 76 chars 
String encoded = new String(java.util.Base64.getEncoder().encode(value.getBytes()));
System.out.println(encoded.length()); // 84 chars
// decode with rfc2045
String decoded = new String(java.util.Base64.getMimeDecoder().decode(encoded.getBytes()));
System.out.println(decoded.equals(value)); // true

它是 java rfc2045 的 Base64 实现中的错误还是允许输入超过 76 个字符的字符串?

Base64 在多个地方使用,在引入 java.util.Base64 之前有多个来源。 76 个字符的限制源于 80 个字符的穿孔卡和旧的单色显示器的行大小。 导致此限制的问题是,在 C 中,读取固定大小缓冲区中的行。

从上面的 javadoc link 可以看出,对于 mime 编码,仍然会生成换行符。解码不需要这样的人为限制。人们不应该对完成更宽松的解码感到惊讶。它不会降低质量。

检查 RFC2045 中 Base64 部分 6.8 中唯一提到 76 个字符限制状态的地方

The encoded output stream must be represented in lines of no more than 76 characters each.

所以这里只提到了编码。

"Quoted-Printable"-第 6.7 节中有一节涉及解码

(5) Encoded lines must not be longer than 76 characters, not counting the trailing CRLF. If longer lines are found in incoming, encoded data, a robust implementation might nevertheless decode the lines, and might report the erroneous encoding to the user.

所以这里明确允许解码太长的行。由于 6.8 根本没有提到解码,我认为适应上一段的规定是公平的。

顺便说一下,java 的 "Mime"-解码器比 "Basic"-解码器更宽松,因为它会忽略非 Base64 字符,而 "Basic"-解码器将拒绝整个输入。