我需要在Java中编码Base64编码中的一些数据。我怎么做呢?提供Base64编码器的类的名称是什么?


我试着利用太阳。BASE64Encoder类,没有成功。我有以下一行Java 7代码:

wr.write(new sun.misc.BASE64Encoder().encode(buf));

我正在使用Eclipse。Eclipse将这一行标记为错误。我导入了所需的库:

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

但同样,它们都显示为错误。我在这里找到了一个类似的帖子。

我使用Apache Commons作为建议的解决方案,包括:

import org.apache.commons.*;

并导入从http://commons.apache.org/codec/下载的JAR文件

但问题仍然存在。Eclipse仍然显示前面提到的错误。我该怎么办?


当前回答

GZIP + Base64

Base64格式的字符串长度比原始长度大:平均133%。因此,首先用GZIP压缩它,然后编码到Base64是有意义的。对于超过200个字符的字符串,它最多可以减少77%。例子:

public static void main(String[] args) throws IOException {
    byte[] original = randomString(100).getBytes(StandardCharsets.UTF_8);

    byte[] base64 = encodeToBase64(original);
    byte[] gzipToBase64 = encodeToBase64(encodeToGZIP(original));

    byte[] fromBase64 = decodeFromBase64(base64);
    byte[] fromBase64Gzip = decodeFromGZIP(decodeFromBase64(gzipToBase64));

    // test
    System.out.println("Original: " + original.length + " bytes, 100%");
    System.out.println("Base64: " + base64.length + " bytes, "
            + (base64.length * 100 / original.length) + "%");
    System.out.println("GZIP+Base64: " + gzipToBase64.length + " bytes, "
            + (gzipToBase64.length * 100 / original.length) + "%");

    //Original: 3700 bytes, 100%
    //Base64: 4936 bytes, 133%
    //GZIP+Base64: 2868 bytes, 77%

    System.out.println(Arrays.equals(original, fromBase64)); // true
    System.out.println(Arrays.equals(original, fromBase64Gzip)); // true
}
public static byte[] decodeFromBase64(byte[] arr) {
    return Base64.getDecoder().decode(arr);
}

public static byte[] encodeToBase64(byte[] arr) {
    return Base64.getEncoder().encode(arr);
}
public static byte[] decodeFromGZIP(byte[] arr) throws IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(arr);
    GZIPInputStream gzip = new GZIPInputStream(bais);
    return gzip.readAllBytes();
}

public static byte[] encodeToGZIP(byte[] arr) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(baos);
    gzip.write(arr);
    gzip.finish();
    return baos.toByteArray();
}
public static String randomString(int count) {
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < count; i++) {
        str.append(" ").append(UUID.randomUUID().toString());
    }
    return str.toString();
}

请参见:如何获取sun.misc的JAR文件。BASE64Encoder课吗?

其他回答

在Java 7中,我编写了这个方法

import javax.xml.bind.DatatypeConverter;

public static String toBase64(String data) {
    return DatatypeConverter.printBase64Binary(data.getBytes());
}

您需要更改类的导入:

import org.apache.commons.codec.binary.Base64;

然后将您的类更改为使用Base64类。

下面是一些示例代码:

byte[] encodedBytes = Base64.encodeBase64("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));

然后阅读为什么你不应该使用太阳。*包。


更新(2016-12-16)

您现在可以使用java.util。使用Java 8的Base64。首先,像往常一样导入它:

import java.util.Base64;

然后使用Base64静态方法,如下:

byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));

如果你想直接编码字符串并得到编码后的结果,你可以使用这个:

String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());

更多信息请参见Base64的Java文档。

与番石榴

pom.xml:

<dependency>
   <artifactId>guava</artifactId>
   <groupId>com.google.guava</groupId>
   <type>jar</type>
   <version>14.0.1</version>
</dependency>

示例代码:

// encode
String s = "Hello Việt Nam";
String base64 = BaseEncoding.base64().encode(s.getBytes("UTF-8"));

// decode
System.out.println("Base64:" + base64); // SGVsbG8gVmnhu4d0IE5hbQ==
byte[] bytes = BaseEncoding.base64().decode(base64);
System.out.println("Decoded: " + new String(bytes, "UTF-8")); // Hello Việt Nam

Eclipse给您一个错误/警告,因为您试图使用特定于JDK供应商的内部类,而不是公共API的一部分。Jakarta Commons提供了自己的base64编解码器实现,当然这些实现位于不同的包中。删除这些导入,并让Eclipse为您导入适当的Commons类。

在Java 8中,它可以这样做: Base64.getEncoder () .encodeToString (string.getBytes (StandardCharsets.UTF_8))

下面是一个简短、完整的例子:

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Temp {
    public static void main(String... args) throws Exception {
        final String s = "old crow medicine show";
        final byte[] authBytes = s.getBytes(StandardCharsets.UTF_8);
        final String encoded = Base64.getEncoder().encodeToString(authBytes);
        System.out.println(s + " => " + encoded);
    }
}

输出:

old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==