当前位置: 首页 > 知识库问答 >
问题:

Java 8 java.util.Base64是不是sun.misc.BASE64的降代?

钮才哲
2023-03-14

问题

Java 8 JAVA.util.Base64 MIME 编码器和解码器是否是不受支持的内部 Java API sun.misc.BASE64 编码器sun.misc.BASE64 解码器的直接替代品?

< sub >编辑(澄清):我所说的直接替换是指我可以使用< code > sun . misc . Base64 Encoder 和< code > sun . misc . Base64 Decoder 将遗留代码透明地切换到任何现有的其他客户端代码的Java 8 MIME Base64编码器/解码器。

到目前为止我的想法和原因

根据我的调查和快速测试(见下面的代码),它应该是一个直接的替代品,因为

  • sun.misc。基于JavaDoc的BASE64编码器是RFC1521中指定的BASE44字符编码器。此RFC是MIME规范的一部分…
  • java.util。Base64基于其JavaDoc使用RFC 2045表1中指定的“Base64字母表”进行MIME下的编码和解码操作

假设RFC 1521和2045没有重大变化(我找不到任何变化),并根据我使用Java8 Base64 MIME编码器/解码器的快速测试应该没问题。

我要找的东西

  • 确认或反驳“插入式替换”点的权威来源,或
  • 一个反例,它显示了一个案例,其中 Java.util.Base64 的行为与 sun.misc.BASE64 编码器 OpenJDK Java 8 实现 (8u40-b25) (BASE64解码器) 或
  • 无论你认为什么,都绝对回答上面的问题

供参考

我的测试代码

public class Base64EncodingDecodingRoundTripTest {

    public static void main(String[] args) throws IOException {
        String test1 = " ~!@#$%^& *()_+=`| }{[]\\;: \"?><,./ ";
        String test2 = test1 + test1;

        encodeDecode(test1);
        encodeDecode(test2);
    }

    static void encodeDecode(final String testInputString) throws IOException {
        sun.misc.BASE64Encoder unsupportedEncoder = new sun.misc.BASE64Encoder();
        sun.misc.BASE64Decoder unsupportedDecoder = new sun.misc.BASE64Decoder();

        Base64.Encoder mimeEncoder = java.util.Base64.getMimeEncoder();
        Base64.Decoder mimeDecoder = java.util.Base64.getMimeDecoder();

        String sunEncoded = unsupportedEncoder.encode(testInputString.getBytes());
        System.out.println("sun.misc encoded: " + sunEncoded);

        String mimeEncoded = mimeEncoder.encodeToString(testInputString.getBytes());
        System.out.println("Java 8 Base64 MIME encoded: " + mimeEncoded);

        byte[] mimeDecoded = mimeDecoder.decode(sunEncoded);
        String mimeDecodedString = new String(mimeDecoded, Charset.forName("UTF-8"));

        byte[] sunDecoded = unsupportedDecoder.decodeBuffer(mimeEncoded); // throws IOException
        String sunDecodedString = new String(sunDecoded, Charset.forName("UTF-8"));

        System.out.println(String.format("sun.misc decoded: %s | Java 8 Base64 decoded:  %s", sunDecodedString, mimeDecodedString));

        System.out.println("Decoded results are both equal: " + Objects.equals(sunDecodedString, mimeDecodedString));
        System.out.println("Mime decoded result is equal to test input string: " + Objects.equals(testInputString, mimeDecodedString));
        System.out.println("\n");
    }
}

共有3个答案

游皓
2023-03-14
匿名用户

rfc1521 和 rfc2045 之间的 base64 规范没有变化。

所有base64实现都可以被认为是彼此的直接替换,base64实现之间的唯一区别是:

  1. 使用的字母表。
  2. 提供了API(例如,有些可能只对完整的输入缓冲区采取行动,而另一些可能是有限状态机,允许您继续通过它们推送输入块,直到完成)。

在RFC版本之间,MIME base64字母表保持不变(必须这样做,否则旧软件会中断),并且是:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/

正如Wikipedia所指出的,base64实现之间只能更改最后2个字符。

作为确实更改了最后 2 个字符的 base64 实现的示例,IMAP MUTF-7 规范使用以下 base64 字母表:

更改的原因是< code>/字符通常用作路径分隔符,并且由于MUTF-7编码用于将非ASCII目录路径展平为ASCII,因此需要在编码段中避免< code>/字符。

盖晋
2023-03-14

我有同样的问题,当我从sun移动到java.util.base64,但后来org.apache.commons.codec.binary.Base64解决了我的问题

喻元龙
2023-03-14

下面是一个小测试程序,它说明了编码字符串的差异:

byte[] bytes = new byte[57];
String enc1 = new sun.misc.BASE64Encoder().encode(bytes);
String enc2 = new String(java.util.Base64.getMimeEncoder().encode(bytes),
                         StandardCharsets.UTF_8);

System.out.println("enc1 = <" + enc1 + ">");
System.out.println("enc2 = <" + enc2 + ">");
System.out.println(enc1.equals(enc2));

其输出为:

enc1 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>
enc2 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
false

请注意,< code > sun . misc . base64 encoder 的编码输出在末尾有一个换行符。它并不总是追加一个换行符,但是如果编码字符串的最后一行正好有76个字符,它就会这样做。(< code>java.util.Base64的作者认为这是< code > sun . misc . base64 encoder 实现中的一个小错误,请参见评论主题)。

这似乎是一件小事,但是如果您有一个依赖于此特定行为的程序,则切换编码器可能会导致输出格式不正确。因此,我的结论是,Java.util.Base64 不是太阳.杂项.BASE64 编码器的直接替代品。

当然,java.util的意图是。Base64是一种功能等效、符合RFC、高性能、完全受支持且指定的替换,旨在支持从sun.misc.BASE64Encoder

 类似资料:
  • 问题内容: 题 Java 8 MIME编码器和解码器是否可以 _ 替代_ 不支持的内部Java API 和? 编辑(澄清):通过直接 _ 替换,_ 我的意思是我可以使用或透明地将任何其他现有客户端代码的Java 8 MIME Base64编码器/解码器切换为旧代码。 我到目前为止的想法以及原因 根据我的调查和快速测试(请参见下面的代码), _ 它应该是直接替代品,_ 因为 基于其JavaDoc的是

  • 问题内容: 我正在使用postgreSQL。我有一列: 但是,当我想插入带有空字符串的行时,如下所示: 它不会给我错误并接受。如何检查插入值应为?(既不为空也不为空) PS: 我的专栏定义为: 问题答案: 向列定义添加约束。例如类似: 有关更多信息,请参见http://www.postgresql.org/docs/current/static/ddl- constraints.html

  • 本文向大家介绍什么是熔断?什么是服务降级?相关面试题,主要包含被问及什么是熔断?什么是服务降级?时的应答技巧和注意事项,需要的朋友参考一下 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。 服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其

  • 本文向大家介绍梯度下降法找到的一定是下降最快的方向么?相关面试题,主要包含被问及梯度下降法找到的一定是下降最快的方向么?时的应答技巧和注意事项,需要的朋友参考一下 并不是,它只是目标函数在当前的点的切平面上下降最快的方向,牛顿方向才一般被认为是下降最快的方向

  • 因此,如果数组是int[]arr={1,2,3},它应该返回true,如果它的降序也应该是true,否则它应该返回false,但我的输出总是true。

  • 它不是升序或降序排序。 有可能这样做吗?