Codierung als Base64 in Java


317

Ich muss einige Daten in der Base64-Codierung in Java codieren. Wie mache ich das? Wie heißt die Klasse, die einen Base64-Encoder bereitstellt?


Ich habe versucht, die sun.misc.BASE64EncoderKlasse zu benutzen , ohne Erfolg. Ich habe die folgende Zeile von Java 7-Code:

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

Ich benutze Eclipse. Eclipse markiert diese Zeile als Fehler. Ich habe die erforderlichen Bibliotheken importiert:

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

Aber auch hier werden beide als Fehler angezeigt. Ich habe hier einen ähnlichen Beitrag gefunden .

Ich habe Apache Commons als Lösung verwendet, indem ich Folgendes vorgeschlagen habe:

import org.apache.commons.*;

und Importieren der JAR-Dateien, die heruntergeladen wurden von: http://commons.apache.org/codec/

Das Problem besteht jedoch weiterhin. Eclipse zeigt weiterhin die zuvor genannten Fehler an. Was sollte ich tun?


7
Mein Rat: Lesen Sie die Fehlermeldung und versuchen Sie zu verstehen, was darin steht.
JB Nizet

27
Sie sollten keine Klassen untersun.**
onon15

16
Sie sind nicht Teil der öffentlichen API. Sie können ohne vorherige Ankündigung geändert, entfernt oder was auch immer. Einige von ihnen sind möglicherweise experimentell oder einfach nicht in Produktionsqualität. oracle.com/technetwork/java/faq-sun-packages-142232.html
onon15

5
Oder verwenden Sie den JAXB DatatypeConverter, der standardmäßig in Java 6 und höher enthalten ist.
Ian Roberts

9
java.util.Base64 ist in Java 8 verfügbar
earcam

Antworten:


621

Sie müssen den Import Ihrer Klasse ändern:

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

Ändern Sie dann Ihre Klasse, um die Base64-Klasse zu verwenden.

Hier ist ein Beispielcode:

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

Lesen Sie dann, warum Sie sun. * -Pakete nicht verwenden sollten .


Update (2016-12-16)

Sie können es jetzt java.util.Base64mit Java 8 verwenden. Importieren Sie es zunächst wie gewohnt:

import java.util.Base64;

Verwenden Sie dann die statischen Base64-Methoden wie folgt:

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

Wenn Sie eine Zeichenfolge direkt codieren und das Ergebnis als codierte Zeichenfolge erhalten möchten, können Sie Folgendes verwenden:

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

Sehen Informationen finden Java-Dokumentation zu Base64 .


Muss ich ein externes Paket herunterladen, damit dies funktioniert? Wenn ja, welche?
abgebrochen

2
Nein, Sie müssen nichts herunterladen afaik
pratnala

16
org.apache.commons.codec.binary.Base64 sieht nicht wie eine Standardbibliothek aus. Ich denke, Sie müssen dafür Apache Commons einschließen. Recht?
Robert Reiz

@Frank Das Decodieren der Bytes auf einmal löst einen OutOfMemory-Fehler aus. Jede Idee verarbeitet sie im Puffer
xyz

Bitte setzen Sie das Update über die alte Lösung.
Zon

225

Verwenden Sie die nie zu spät kommende Java 8-Klasse, um am Spaß teilzunehmen: java.util.Base64

new String(Base64.getEncoder().encode(bytes));

11
Beachten Sie, dass Sie, obwohl dies ein trivialer Kommentar ist, nicht mit älteren Java-Versionen kompatibel sind, die (zumindest zu diesem Zeitpunkt) wahrscheinlich weitaus häufiger vorkommen.
dcoder

Ich würde auch wählen, Java 8 Klasse ist möglich. Ich arbeite derzeit an einer Klasse, um die Apache Commons-Bibliothek aus unserem Frühlingsprojekt zu entfernen. Die meisten Dinge können einfach durch Methoden aus Spring-Bibliotheken oder jdk ersetzt werden.
Adrian Cosma

68

In Java 8 kann dies wie folgt erfolgen: Base64.getEncoder (). EncodeToString (string.getBytes (StandardCharsets.UTF_8))

Hier ist ein kurzes, in sich geschlossenes vollständiges Beispiel:

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

Ausgabe:

old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==

3
Warum gibt es in der Java-Standardbibliothek keine Zeichensatzkonstanten, oh warum?!
Lukasz Wiktor

4
Gute Frage, Lukasz! Eigentlich gibt es. Ich habe vergessen! java.nio.charset.StandardCharsets. Ich werde meine Antwort bearbeiten. Siehe stackoverflow.com/questions/1684040/…
Kirby

67

Sie können auch mit Base64-Codierung konvertieren. Dazu können Sie die verwendenjavax.xml.bind.DatatypeConverter#printBase64Binary Methode verwenden.

Zum Beispiel:

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

4
Während dies funktioniert, heißt es in der Dokumentation speziell: DatatypeConverterInterface ist nur für JAXB-Anbieter bestimmt.
gebirgsbärbel

11
Ich denke, dass @gebirgsbaerbel falsch ist, printX () und parseX () können von jedem verwendet werden. Das einzige, was nur für JAXB gilt, ist die setDatatypeConverter()Methode (die dann für JAXB-Anbieter aufgerufen werden muss).
PhoneixS

9
Schließlich wird die Base64 - Klasse von Java 8 wird der Weg zu gehen. Wenn Sie jedoch in der Zwischenzeit auf Java 7 abzielen müssen, ist diese Lösung hilfreich, da sie nicht auf externen Bibliotheken basiert.
Dana

4
Dies funktioniert nicht unter Java 9. Schlimmer noch, Code, der mit javax.xml.bind für Java 7 kompiliert wurde. * Schlägt zur Laufzeit unter Java 9 fehl.
Stephen M - am Streik -

21

Google Guava ist eine weitere Option zum Codieren und Decodieren von Base64-Daten:

POM-Konfiguration:

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

Beispielcode:

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

10

Eclipse gibt einen Fehler / eine Warnung aus, da Sie versuchen, interne Klassen zu verwenden, die für einen JDK-Anbieter spezifisch sind und nicht Teil der öffentlichen API sind. Jakarta Commons bietet eine eigene Implementierung von base64-Codecs an, die sich natürlich in einem anderen Paket befinden. Löschen Sie diese Importe und lassen Sie Eclipse die richtigen Commons-Klassen für Sie importieren.


Das Jakarta-Projekt gibt es nicht mehr . Es wurde gemischt und abgeglichen (und der Name für Java EE wiederverwendet ). Können Sie Ihre Antwort aktualisieren und einige Referenzen angeben? Ist es zum Beispiel jetzt Klasse Base64inorg.apache.commons.codec.binary ? Ist es jetzt Apache Commons für diesen Kontext?
Peter Mortensen

Sie können gerne meine Antwort bearbeiten.
Marko Topolnik

9

Um dies zu konvertieren, benötigen Sie einen Encoder und Decoder, den Sie von Base64Coder erhalten - einem Open-Source-Base64-Encoder / Decoder in Java . Es ist die Datei Base64Coder.java, die Sie benötigen.

Um nun gemäß Ihren Anforderungen auf diese Klasse zugreifen zu können, benötigen Sie die folgende Klasse:

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

In Android können Sie Ihre Bitmap zum Hochladen auf einen Server oder Webdienst in Base64 konvertieren.

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

Dieses "encodedImage" ist eine Textdarstellung Ihres Bildes. Sie können dies entweder zum Hochladen oder zum direkten Anzeigen in eine HTML-Seite wie folgt verwenden ( Referenz ):

<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" />

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


Der letzte Link (dwij.co.in) ist defekt (404).
Peter Mortensen


9

Hier sind meine zwei Cent ... Java 8 enthält eine eigene Implementierung von Base64 . Ich fand jedoch einen etwas störenden Unterschied. Zur Veranschaulichung werde ich ein Codebeispiel bereitstellen:

Mein Codec-Wrapper:

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

Testklasse:

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

AUSGABE:

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)

Beachten Sie, dass der Apache-codierte Text am Ende zusätzliche Zeilenumbrüche (Leerzeichen) enthält. Daher musste ich trim()den Apache-codierten Text aufrufen, damit mein Codec unabhängig von der Base64-Implementierung das gleiche Ergebnis liefert . In meinem Fall habe ich den oben genannten Methodenaufruf einfach apacheDecode()wie folgt zu meinen Codecs hinzugefügt :

return Base64.encodeBase64String(decodedByteArr).trim();

Nachdem diese Änderung vorgenommen wurde, erwartete ich zunächst folgende Ergebnisse:

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!

SCHLUSSFOLGERUNG : Wenn Sie von Apache Base64 zu Java wechseln möchten, müssen Sie:

  1. Dekodieren Sie codierten Text mit Ihrem Apache-Decoder.
  2. Codieren Sie den resultierenden (einfachen) Text mit Java.

Wenn Sie wechseln, ohne diese Schritte auszuführen, treten höchstwahrscheinlich Probleme auf. So habe ich diese Entdeckung gemacht.


8

Verwenden Sie unter Android die statischen Methoden der Dienstprogrammklasse android.util.Base64 . Die Dokumentation, auf die verwiesen wird, besagt, dass die Base64-Klasse in API-Level 8 ( Android 2.2 (Froyo)) hinzugefügt wurde .

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

Dies ist die beste Antwort, wenn Sie für Android entwickeln und Java 8 nicht verwenden können.
Craig Brown

6

Apache Commons hat eine schöne Implementierung von Base64. Sie können dies so einfach tun wie:

// 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));

Weitere Informationen zur Base64-Codierung finden Sie unter Base64-Codierung mit Java und JavaScript .


Beachten Sie, dass dies voraussetzt, dass die Zeichenfolge im Standardzeichensatz
Kirby

6

Wenn Sie Spring Framework mindestens Version 4.1 verwenden, können Sie die Klasse org.springframework.util.Base64Utils verwenden :

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

Es wird an Java 8 Base64, Apache Commons Codec oder JAXB DatatypeConverter delegiert, je nachdem, was verfügbar ist.


4

Einfaches Beispiel mit Java 8:

import java.util.Base64;

String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));

3

In Java 7 habe ich diese Methode codiert

import javax.xml.bind.DatatypeConverter;

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

Funktioniert unter Java 7 und 8, aber nicht unter Java 9. Schlimmer noch, wenn Sie dies unter Java 7 oder 8 erstellen, wird es erstellt und Sie erhalten zur Laufzeit unter Java 9 eine ClassDefNotFoundException.
Stephen M -on strike-


1

Ich habe es mit dem folgenden Code-Snippet versucht. Es hat gut funktioniert. :-)

com.sun.org.apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");

0
public String convertImageToBase64(String filePath) {
    byte[] fileContent = new byte[0];
    String base64encoded = null;
    try {
        fileContent = FileUtils.readFileToByteArray(new File(filePath));
    } catch (IOException e) {
        log.error("Error reading file: {}", filePath);
    }
    try {
        base64encoded = Base64.getEncoder().encodeToString(fileContent);
    } catch (Exception e) {
        log.error("Error encoding the image to base64", e);
    }
    return base64encoded;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.