JavaでBase64としてエンコード


317

JavaのBase64エンコーディングで一部のデータをエンコードする必要があります。それ、どうやったら出来るの?Base64エンコーダーを提供するクラスの名前は何ですか?


私はsun.misc.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は以前に言及されたエラーをまだ示しています。私は何をすべきか?


7
私のアドバイス:エラーメッセージを読み、それが何を言っているのかを理解してください。
JBニゼット2012年

27
以下のクラスを使用することは想定されていませんsun.**
onon15

16
これらはパブリックAPIの一部ではありません。それらは予告なしに変更、削除などされます。それらのいくつかは実験的であるか、または単に生産グレードではないかもしれません。 oracle.com/technetwork/java/faq-sun-packages-142232.html
onon15

5
または、Java 6以降に標準で含まれているJAXB DatatypeConverter使用します
Ian Roberts

9
java.util.Base64はJava 8で利用可能
earcam '05 / 10/05

回答:


621

クラスのインポートを変更する必要があります:

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

次に、sun。*パッケージを使用しない理由をお読みください


アップデート(2016-12-16)

これjava.util.Base64でJava 8を使用できるようになります。最初に、通常どおりにインポートします。

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ドキュメントを参照してください。


これを機能させるには、外部パッケージをダウンロードする必要がありますか?はいの場合、どちらですか?
2014年

2
Afaikをダウンロードする必要はありません
プラトナラ

16
org.apache.commons.codec.binary.Base64はデフォルトのライブラリのようには見えません。そのためにはApache Commonsを含める必要があると思います。正しい?
Robert Reiz

@Frankバイトを一度にデコードすると、OutOfMemoryエラーが発生します。任意のアイデアがバッファで処理します
xyz

225

Java 8の決して遅すぎることのない楽しいクラスを使用します。 java.util.Base64

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

11
些細なコメントですが、これを使用する場合、Javaの古いバージョンと互換性がないことに注意してください。Javaの古いバージョン(少なくとも現時点では)はおそらくはるかに普及しています。
デコーダー2014

Java 8のクラスを選択することも可能です。現在、SpringプロジェクトからApache Commonsライブラリを削除するクラスに取り組んでいます。ほとんどのものは、Springライブラリまたはjdkのメソッドで簡単に置き換えることができます。
エイドリアンコスマ

68

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==

3
Java標準ライブラリにCharset定数がないのはなぜですか?
Lukasz Wiktor 2014年

4
いい質問だ、ルカシュ!実はあります。忘れてた!java.nio.charset.StandardCharsets。回答を編集します。stackoverflow.com/questions/1684040/…を
Kirby

67

Base64エンコーディングを使用して変換することもできます。これを行うには、javax.xml.bind.DatatypeConverter#printBase64Binaryメソッドを使用できます。

例えば:

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

4
これは機能しますが、ドキュメントには具体的に次のように記載されています。DatatypeConverterInterfaceはJAXBプロバイダー専用です。
gebirgsbärbel

11
@gebirgsbaerbelは間違っていると思います。printX()およびparseX()メソッドは誰でも使用できます。JAXB専用の唯一のsetDatatypeConverter()方法はメソッドです(JAXBプロバイダー用に呼び出す必要があります)。
PhoneixS 2014年

9
最終的にはJavaの8からのBase64クラスは次のようになります移動するための方法。ただし、その間にJava 7を対象とする必要がある場合は、外部ライブラリに依存しないため、このソリューションは優れています。
ダナ

4
。これは、悪いことjavax.xml.bindのを使用してJava 7用にコンパイルされたコード* Javaの9の下に実行時に失敗するJava 9の下に動作しません
スティーブン・Mはstrike- -on

21

Google Guavaは、Base64データをエンコードおよびデコードするもう1つの選択肢です。

POM構成:

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

サンプルコード:

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

パブリックAPIの一部ではなく、JDKベンダーに固有の内部クラスを使用しようとしているため、Eclipseはエラー/警告を出します。Jakarta Commonsは、base64コーデックの独自の実装を提供します。もちろん、これは別のパッケージにあります。それらのインポートを削除し、Eclipseに適切なCommonsクラスをインポートさせます。


Jakartaプロジェクトは、もはやありません。それは混合され、一致しました(そしてその名前はJava EEで再利用されました)。回答を更新して、いくつかの参照を提供できますか?例えば、それは今あるクラスBase64ではorg.apache.commons.codec.binary?現在、このコンテキストのApache Commonsですか?
Peter Mortensen

9

これを変換するには、Base64Coder(JavaのオープンソースのBase64エンコーダー/デコーダー)から取得するエンコーダーとデコーダーが必要です。これは、必要な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);
        }
    }
}

Androidでは、サーバーまたはWebサービスにアップロードするためにビットマップをBase64に変換できます。

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

この「encodedImage」は画像のテキスト表現です。これをアップロードの目的で、または以下のように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" />

ドキュメンテーション: http //dwij.co.in/java-base64-image-encoder


最後のリンク(dwij.co.in)は壊れています(404)。
Peter Mortensen


9

これが私の2セントです... Java 8には独自のBase64の実装が含まれています。しかし、少し気になる違いを見つけました。説明のために、コード例を示します。

私のコーデックラッパー:

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

テストクラス:

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

出力:

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)

Apacheでエンコードされたテキストには、末尾に追加の改行(空白)が含まれていることに注意してください。したがって、Base64の実装に関係なく、私のコーデックで同じ結果が得られるようtrim()にするには、Apacheでエンコードされたテキストを呼び出す必要がありました。私の場合、前述のメソッド呼び出しをapacheDecode()次のようにコーデックに追加しました。

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

この変更が行われると、結果は私が最初に期待したとおりです。

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!

結論:Apache Base64からJavaに切り替える場合は、次のことを行う必要があります。

  1. エンコードされたテキストをApacheデコーダーでデコードします。
  2. 結果の(プレーン)テキストをJavaでエンコードします。

これらの手順を実行せずに切り替えると、問題が発生する可能性が高くなります。それが私がこの発見をした方法です。


8

Androidでは、android.util.Base64ユーティリティクラスの静的メソッドを使用します。参照ドキュメントには、Base64クラスがAPIレベル8(Android 2.2(Froyo))で追加されたと記載されています。

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

あなたは、Androidのために開発しているとは、Java 8を使用することができない場合、これが最良の答えです
クレイグ・ブラウン

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

base64エンコーディングの詳細については、JavaおよびJavaScriptを使用したBase64エンコーディングを参照してください。


これは、文字列を前提としていますが、デフォルトの文字セットでエンコードされた
星のカービィ

6

あなたが使用している場合は春のフレームワークを少なくともバージョン4.1には、使用することができますorg.springframework.util.Base64Utilsのクラスを:

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

利用可能なものに応じて、Java 8のBase64、Apache Commons Codec、またはJAXB DatatypeConverterに委任します。


4

Java 8の簡単な例:

import java.util.Base64;

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

3

Java 7では、このメソッドをコーディングしました

import javax.xml.bind.DatatypeConverter;

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

Javaの7で動作し、8ではなく、Javaの9.さらに悪いことに、あなたはJavaの7または8の下にこれを構築する場合、それが構築され、その後は、Java 9.下ランタイムでClassDefNotFoundExceptionを取得します
strike- -onスティーブン・M


1

次のコードスニペットを試してみました。うまくいきました。:-)

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.