Java 8 java.util.Base64是否可以替代sun.misc.BASE64? [英] Is Java 8 java.util.Base64 a drop-in replacement for sun.misc.BASE64?

查看:287
本文介绍了Java 8 java.util.Base64是否可以替代sun.misc.BASE64?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

Java 8 java.util.Base64 MIME编码器和解码器 是不受支持的内部Java API sun.misc.BASE64Encodersun.misc.BASE64Decoder的直接替代 吗?

Are the Java 8 java.util.Base64 MIME Encoder and Decoder a drop-in replacement for the unsupported, internal Java API sun.misc.BASE64Encoder and sun.misc.BASE64Decoder?

编辑(澄清):通过 直接替换 我的意思是,我可以使用sun.misc.BASE64Encodersun.misc.BASE64Decoder透明地将旧代码转换为Java 8 MIME Base64编码器/解码器,以透明地存在任何其他现有客户端代码.

EDIT (Clarification): By drop-in replacement I mean that I can switch legacy code using sun.misc.BASE64Encoder and sun.misc.BASE64Decoder to Java 8 MIME Base64 Encoder/Decoder for any existing other client code transparently.

我到目前为止的想法以及原因

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

Based on my investigation and quick tests (see code below) it should be a drop-in replacement because

    根据其JavaDoc的
  • sun.misc.BASE64Encoder RFC1521 中指定的BASE64字符编码器.该RFC是 MIME 规范的一部分...
  • java.util.Base64基于其 JavaDoc 使用"Base64字母"按照 MIME
  • 下的 RFC 2045 表1中指定的用于编码和解码操作...
  • sun.misc.BASE64Encoder based on its JavaDoc is a BASE64 Character encoder as specified in RFC1521. This RFC is part of the MIME specification...
  • java.util.Base64 based on its JavaDoc Uses the "The Base64 Alphabet" as specified in Table 1 of RFC 2045 for encoding and decoding operation... under MIME

假设RFC 1521和2045中没有重大更改(我找不到任何更改),并且基于使用Java 8 Base64 MIME编码器/解码器的快速测试,应该没问题.

Assuming no significant changes in the RFC 1521 and 2045 (I could not find any) and based on my quick test using the Java 8 Base64 MIME Encoder/Decoder should be fine.

我在寻找什么

    权威来源确认或反驳即插即用".点或
  • 一个反例,显示java.util.Base64与sun.misc.BASE64Encoder具有不同行为的情况
  • an authoritative source confirming or disproving the "drop-in replacement" point OR
  • a counterexample which shows a case where java.util.Base64 has different behaviour than the sun.misc.BASE64Encoder OpenJDK Java 8 implementation (8u40-b25) (BASE64Decoder) OR
  • whatever you think answers above question definitely

供参考

我的测试代码

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");
    }
}

推荐答案

下面是一个小型测试程序,它说明了编码字符串的不同之处:

Here's a small test program that illustrates a difference in the encoded strings:

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

请注意,sun.misc.BASE64Encoder的编码输出在末尾有换行符.它不会总是附加一个换行符,但是如果编码字符串的最后一行恰好有76个字符,它就会这样做. (java.util.Base64的作者认为这是sun.misc.BASE64Encoder实现中的一个小错误–请参阅

Note that the encoded output of sun.misc.BASE64Encoder has a newline at the end. It doesn't always append a newline, but it happens to do so if the encoded string has exactly 76 characters on its last line. (The author of java.util.Base64 considered this to be a small bug in the sun.misc.BASE64Encoder implementation – see the review thread).

这似乎有些琐碎,但如果您有一个依赖于此特定行为的程序,则切换编码器可能会导致输出格式错误.因此,我得出结论,java.util.Base64不是sun.misc.BASE64Encoder的直接替代品.

This might seem like a triviality, but if you had a program that relied on this specific behavior, switching encoders might result in malformed output. Therefore, I conclude that java.util.Base64 is not a drop-in replacement for sun.misc.BASE64Encoder.

当然,java.util.Base64 intent 是它是功能上等效的,符合RFC,高性能,完全受支持且指定的替换,旨在支持将代码从.不过,在迁移时,您需要注意一些类似的极端情况.

Of course, the intent of java.util.Base64 is that it's a functionally equivalent, RFC-conformant, high-performance, fully supported and specified replacement that's intended to support migration of code away from sun.misc.BASE64Encoder. You need to be aware of some edge cases like this when migrating, though.

这篇关于Java 8 java.util.Base64是否可以替代sun.misc.BASE64?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆