Java中的Base64编码

Jur*_*y A 302 java base64

我正在使用Eclipse.我有以下代码行:

wr.write(new sun.misc.BASE64Encoder().encode(buf));
Run Code Online (Sandbox Code Playgroud)

Eclipse将此行标记为错误.我导入了所需的库:

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
Run Code Online (Sandbox Code Playgroud)

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

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

import org.apache.commons.*;
Run Code Online (Sandbox Code Playgroud)

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

但问题仍然存在.Eclipse仍然显示前面提到的错误; 请指教.

Fra*_*ank 597

您需要更改班级的导入:

import org.apache.commons.codec.binary.Base64;
Run Code Online (Sandbox Code Playgroud)

然后更改您的Class以使用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));
Run Code Online (Sandbox Code Playgroud)

然后阅读为什么你不应该使用sun.*包.


更新(2016年12月16日)

你现在可以java.util.Base64用Java8了.首先,像往常一样导入它:

import java.util.Base64;
Run Code Online (Sandbox Code Playgroud)

然后使用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));
Run Code Online (Sandbox Code Playgroud)

如果您想直接编码字符串并将结果作为编码字符串,则可以使用此字符串.

String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Javadocs for Base64:https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html

  • org.apache.commons.codec.binary.Base64看起来不像默认库.我想你必须包括apache commons.对? (16认同)
  • 不,你不需要下载任何东西 (2认同)

bra*_*tan 218

使用Java 8永远不会太晚加入有趣的类: java.util.Base64

  • 虽然是一个微不足道的评论,但请注意,如果你使用它与旧版本的Java不兼容,那么(至少在这个时间点)它可能更为普遍. (11认同)
  • http://ykchee.blogspot.com/2014/03/base64-in-java-8-its-not-too-late-to.html (4认同)
  • 首选返回 `String` 类型的函数: `Base64.getEncoder().encodeToString("blah".getBytes())` (3认同)

sti*_*ike 66

您也可以使用base64编码进行转换.为此,您可以使用javax.xml.bind.DatatypeConverter#printBase64Binary方法

例如:

byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));
Run Code Online (Sandbox Code Playgroud)

  • 我认为@gebirgsbaerbel是错误的,printX()和parseX()方法可以被任何人使用,唯一适用于JAXB的是[`setDatatypeConverter()`](http://docs.oracle.com/ javase/6/docs/api/javax/xml/bind/DatatypeConverter.html #setDatatypeConverter(javax.xml.bind.DatatypeConverterInterface))方法(然后必须为JAXB提供程序调用). (11认同)
  • 最终,来自Java 8的Base64类将是**的方式.但是如果你必须同时针对Java 7,这个解决方案很好,因为它不依赖于外部库. (9认同)
  • 虽然这有效,但文档特别指出:DatatypeConverterInterface仅供JAXB提供程序使用. (4认同)
  • 这在Java 9下不起作用.更糟糕的是,使用javax.xml.bind.*为Java 7编译的代码在运行时将在Java 9下失败. (4认同)

Kir*_*rby 66

在Java 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个简短,独立的完整示例

old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==
Run Code Online (Sandbox Code Playgroud)

给出输出

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好问题,卢卡斯!实际上,有.我忘了!`java.nio.charset.StandardCharsets`.我会编辑我的答案.请参阅http://stackoverflow.com/questions/1684040/java-why-charset-names-are-not-constants (4认同)
  • 为什么Java标准库中没有Charset常量,为什么?! (3认同)

Tho*_*Tho 20

Google Guava是编码和解码base64数据的不错选择:

POM配置:

<dependency>
   <artifactId>guava</artifactId>
   <groupId>com.google.guava</groupId>
   <type>jar</type>
   <version>14.0.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

示例代码:

String inputContent = "Hello Vi?t Nam";
String base64String = BaseEncoding.base64().encode(inputContent.getBytes("UTF-8"));

// Decode
System.out.println("Base64:" + base64String); // SGVsbG8gVmnhu4d0IE5hbQ==
byte[] contentInBytes = BaseEncoding.base64().decode(base64String);
System.out.println("Source content: " + new String(contentInBytes, "UTF-8")); // Hello Vi?t Nam
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 10

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


Ale*_*rov 9

对于java 6-7,最好的选择是从Android存储库借用代码.它没有依赖关系.

https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java


hfo*_*nez 9

这是我的两分钱...... Java 8确实包含了自己的实现trim().但是,我发现了一个有点令人不安的差异.为了说明,我将提供一个代码示例:

我的CODEC包装:

public interface MyCodec
{
  static String apacheDecode(String encodedStr)
  {
    return new String(Base64.decodeBase64(encodedStr), Charset.forName("UTF-8"));
  }

  static String apacheEncode(String decodedStr)
  {
    byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
    return Base64.encodeBase64String(decodedByteArr);
  }

  static String javaDecode(String encodedStr)
  {
    return new String(java.util.Base64.getDecoder().decode(encodedStr), Charset.forName("UTF-8"));
  }

  static String javaEncode(String decodedStr)
  {
    byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
    return java.util.Base64.getEncoder().encodeToString(decodedByteArr);
  }
}
Run Code Online (Sandbox Code Playgroud)

测试类:

public class CodecDemo
{
  public static void main(String[] args)
  {
    String decodedText = "Hello World!";

    String encodedApacheText = MyCodec.apacheEncode(decodedText);
    String encodedJavaText = MyCodec.javaEncode(decodedText);

    System.out.println("Apache encoded text: " + MyCodec.apacheEncode(encodedApacheText));
    System.out.println("Java encoded text: " + MyCodec.javaEncode(encodedJavaText));

    System.out.println("Encoded results equal: " + encodedApacheText.equals(encodedJavaText));

    System.out.println("Apache decode Java: " + MyCodec.apacheDecode(encodedJavaText));
    System.out.println("Java decode Java: " + MyCodec.javaDecode(encodedJavaText));

    System.out.println("Apache decode Apache: " + MyCodec.apacheDecode(encodedApacheText));
    System.out.println("Java decode Apache: " + MyCodec.javaDecode(encodedApacheText));
  }
}
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA0K

Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: false
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character d
    at java.util.Base64$Decoder.decode0(Base64.java:714)
    at java.util.Base64$Decoder.decode(Base64.java:526)
    at java.util.Base64$Decoder.decode(Base64.java:549)
Run Code Online (Sandbox Code Playgroud)

请注意,Apache编码的文本末尾包含其他换行符(空格).因此,为了使我的CODEC无论Base64实现如何都能产生相同的结果,我不得不调用apacheDecode()Apache编码的文本.就我而言,我只是将上述方法调用添加到我的CODEC中trim(),如下所示:

return Base64.encodeBase64String(decodedByteArr).trim();
Run Code Online (Sandbox Code Playgroud)

一旦做出这种改变,结果就是我期望的结果:

Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: true
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Java decode Apache: Hello World!
Run Code Online (Sandbox Code Playgroud)

也许有人可以评论为什么会这样,但我发现我的解决方案是可接受的妥协.


Web*_*une 8

要转换它,您需要编码器和解码器,您将从http://www.source-code.biz/base64coder/java/获得.它是您需要的File Base64Coder.java.

现在,根据您的要求访问此课程,您将需要以下课程:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Base64 {

    public static void main(String args[]) throws IOException {
        /*
         * if (args.length != 2) {
         *     System.out.println(
         *         "Command line parameters: inputFileName outputFileName");
         *     System.exit(9);
         * } encodeFile(args[0], args[1]);
         */
        File sourceImage = new File("back3.png");
        File sourceImage64 = new File("back3.txt");
        File destImage = new File("back4.png");
        encodeFile(sourceImage, sourceImage64);
        decodeFile(sourceImage64, destImage);
    }

    private static void encodeFile(File inputFile, File outputFile) throws IOException {
        BufferedInputStream in = null;
        BufferedWriter out = null;
        try {
            in = new BufferedInputStream(new FileInputStream(inputFile));
            out = new BufferedWriter(new FileWriter(outputFile));
            encodeStream(in, out);
            out.flush();
        }
        finally {
            if (in != null)
                in.close();
            if (out != null)
                out.close();
        }
    }

    private static void encodeStream(InputStream in, BufferedWriter out) throws IOException {
        int lineLength = 72;
        byte[] buf = new byte[lineLength / 4 * 3];
        while (true) {
            int len = in.read(buf);
            if (len <= 0)
                break;
            out.write(Base64Coder.encode(buf, 0, len));
            out.newLine();
        }
    }

    static String encodeArray(byte[] in) throws IOException {
        StringBuffer out = new StringBuffer();
        out.append(Base64Coder.encode(in, 0, in.length));
        return out.toString();
    }

    static byte[] decodeArray(String in) throws IOException {
        byte[] buf = Base64Coder.decodeLines(in);
        return buf;
    }

    private static void decodeFile(File inputFile, File outputFile) throws IOException {
        BufferedReader in = null;
        BufferedOutputStream out = null;
        try {
            in = new BufferedReader(new FileReader(inputFile));
            out = new BufferedOutputStream(new FileOutputStream(outputFile));
            decodeStream(in, out);
            out.flush();
        }
        finally {
            if (in != null)
                in.close();
            if (out != null)
                out.close();
        }
    }

    private static void decodeStream(BufferedReader in, OutputStream out) throws IOException {
        while (true) {
            String s = in.readLine();
            if (s == null)
                break;
            byte[] buf = Base64Coder.decodeLines(s);
            out.write(buf);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Android中,您可以将Bitmap转换为Base64,以便上传到服务器/ Web服务.

Bitmap bmImage = //Data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageData = baos.toByteArray();
String encodedImage = Base64.encodeArray(imageData);
Run Code Online (Sandbox Code Playgroud)

这个"encodedImage"是你的Image的文本表示.您可以将其用于上传目的或直接插入HTML页面,如下所示(参考):

<img alt="" src="data:image/png;base64,<?php echo $encodedImage; ?>" width="100px" />
<img alt="" src="data:image/png;base64,/9j/4AAQ...........1f/9k=" width="100px" />
Run Code Online (Sandbox Code Playgroud)

文档:http://dwij.co.in/java-base64-image-encoder


Yoj*_*mbo 8

在Android上,使用android.util.Base64实用程序类的静态方法.参考文档说,在API级别8(Froyo)中添加了Base64类.

import android.util.Base64;

byte[] encodedBytes = Base64.encode("Test".getBytes());
Log.d("tag", "encodedBytes " + new String(encodedBytes));

byte[] decodedBytes = Base64.decode(encodedBytes);
Log.d("tag", "decodedBytes " + new String(decodedBytes));
Run Code Online (Sandbox Code Playgroud)


fai*_*gat 6

apache commons有很好的base64实现.你可以像这样简单地做到这一点

// Encrypt data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(str .getBytes());
System.out.println("ecncoded value is " + new String(bytesEncoded));

// Decrypt data on other side, by processing encoded data
byte[] valueDecoded= Base64.decodeBase64(bytesEncoded );
System.out.println("Decoded value is " + new String(valueDecoded));
Run Code Online (Sandbox Code Playgroud)

您可以在http://faisalbhagat.blogspot.com/2014/06/base64-encoding-using-java-and.html找到有关base64编码的更多详细信息.


Dan*_*eón 6

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

import javax.xml.bind.DatatypeConverter;

public static String toBase64(String data) {
    return DatatypeConverter.printBase64Binary(data.getBytes());
}
Run Code Online (Sandbox Code Playgroud)

  • 在 Java 7 和 8 下工作,但在 Java 9 下不起作用。更糟糕的是,如果您在 Java 7 或 8 下构建它,它将构建,然后您将在 Java 9 下的运行时收到 ClassDefNotFoundException。 (2认同)

z3d*_*3d0 5

Java 8 的简单示例:

import java.util.Base64;

String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
Run Code Online (Sandbox Code Playgroud)


hol*_*s83 5

如果您使用的是Spring Framework至少4.1版,则可以使用org.springframework.util.Base64Utils类:

byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);
Run Code Online (Sandbox Code Playgroud)

它将根据可用的东西委派给Java 8的Base64,Apache Commons Codec或JAXB DatatypeConverter。