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 니 제트

27
당신은 아래 사용 클래스에 안돼요sun.**
onon15

16
그것들은 공개 API의 일부가 아닙니다. 예고없이 변경, 제거 또는 기타 사항이있을 수 있습니다. 그들 중 일부는 실험적이거나 생산 등급이 아닐 수 있습니다. oracle.com/technetwork/java/faq-sun-packages-142232.html
onon15

5
또는 Java 6 이상에 표준으로 포함 된 JAXB DatatypeConverter사용하십시오 .
이안 로버츠

9
java.util.Base64는 자바 8에서 사용할 수 있습니다
earcam

답변:


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.Base64Java 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 설명서를 참조하십시오 .


이것이 작동하려면 외부 패키지를 다운로드해야합니까? 그렇다면 어느 것입니까?
중단

2
당신은 아무것도 다운로드 할 필요가 없습니다
aprik

16
org.apache.commons.codec.binary.Base64는 기본 라이브러리처럼 보이지 않습니다. 나는 당신이 그것에 대한 아파치 공통점을 포함해야한다고 생각합니다. 권리?
Robert Reiz

@Frank 디코딩 버퍼에 한번 인상에 OutOfMemory error.Any 아이디어 프로세스 그것을 바이트
XYZ

225

Java 8의 절대 재미가없는 클래스를 사용하십시오. java.util.Base64

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

11
사소한 의견이지만, 사용하는 경우 이전 버전의 Java와 호환되지 않습니다 (적어도 현재 시점에서).
dcoder

Java 8의 클래스도 가능합니다. 저는 현재 봄 프로젝트에서 Apache Commons 라이브러리를 제거하기 위해 수업을 진행하고 있습니다. 대부분의 물건은 Spring 라이브러리 또는 jdk의 메소드로 쉽게 대체 할 수 있습니다.
Adrian Cosma

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

4
좋은 질문입니다, 루카스! 실제로 있습니다. 잊었다! java.nio.charset.StandardCharsets. 답변을 편집하겠습니다. 참조 stackoverflow.com/questions/1684040/...
커비

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 () 메소드는 모든 사람이 사용할 수 있습니다 setDatatypeConverter().
PhoneixS

9
결국 자바 8에서 Base64로 클래스가 될 것입니다 갈 방법입니다. 그러나 그 동안 Java 7을 대상으로 해야하는 경우이 솔루션은 외부 라이브러리에 의존하지 않기 때문에 좋습니다.
dana

4
Java 9에서는 작동하지 않습니다. 더 나쁜 것은 javax.xml.bind. *를 사용하여 Java 7 용으로 컴파일 된 코드는 Java 9에서는 런타임에서 실패한다는 것입니다.
Stephen M -on strike-

21

Google Guava 는 Base64 데이터를 인코딩 및 디코딩하는 또 다른 선택입니다.

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

Eclipse는 JDK 공급 업체에 고유하고 공개 API의 일부가 아닌 내부 클래스를 사용하려고하기 때문에 오류 / 경고를 표시합니다. Jakarta Commons는 물론 다른 패키지에있는 base64 코덱의 자체 구현을 제공합니다. 해당 가져 오기를 삭제하고 Eclipse가 적절한 Commons 클래스를 가져 오도록하십시오.


자카르타 프로젝트는 더 이상 없다 . 혼합되어 있고 일치합니다 (및 Java EE에 사용 된 이름 ). 답변을 업데이트하고 참고 자료를 제공 할 수 있습니까? 예를 들어 현재 클래스 Base64org.apache.commons.codec.binary ? 이 맥락에서 이제 Apache Commons 입니까?
피터 Mortensen

9

이것을 변환하려면 Java의 오픈 소스 Base64 인코더 / 디코더 인 Base64Coder 에서 얻을 수있는 인코더 및 디코더가 필요합니다 . 필요한 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에서는 서버 나 웹 서비스에 업로드하기 위해 비트 맵을 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 페이지로 직접 재생하기 위해 이것을 사용할 수 있습니다 ( reference ).

<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).
피터 Mortensen


9

여기 내 두 센트가 있습니다 ... 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));

이것은 안드로이드 용으로 개발 중이고 Java 8을 사용할 수없는 경우에 가장 좋은 대답입니다.
Craig Brown

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 인코딩 에서 찾을 수 있습니다 .


이것은 문자열이 기본 문자셋으로 인코딩되어 있다고 가정합니다
Kirby

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이 발생합니다.
Stephen M-on strike-


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.