[java] Java에서 Base64 데이터 디코딩

Base64로 인코딩 된 이미지가 있습니다. Java로 디코딩하는 가장 좋은 방법은 무엇입니까? Sun Java 6에 포함 된 라이브러리 만 사용하시기 바랍니다.



답변

v6부터 Java SE는 JAXB와 함께 제공됩니다. javax.xml.bind.DatatypeConverter이것을 쉽게 만드는 정적 메소드가 있습니다. 참조 parseBase64Binary()printBase64Binary().


답변

현재 자바 8 , Base64 인코딩 및 디코딩을위한 공식적으로 지원되는 API가있다. 시간이 지나면 이것이 기본 선택이 될 것입니다.

API에는 클래스 java.util.Base64와 해당 중첩 클래스가 포함됩니다. 기본, URL 안전 및 MIME의 세 가지 맛을 지원합니다.

“기본”인코딩을 사용하는 샘플 코드 :

import java.util.Base64;

byte[] bytes = "Hello, World!".getBytes("UTF-8");
String encoded = Base64.getEncoder().encodeToString(bytes);
byte[] decoded = Base64.getDecoder().decode(encoded);

문서java.util.Base64 에는 인코더와 디코더를 구성하고 다른 클래스를 입력 및 출력 (바이트 배열, 문자열, ByteBuffer, java.io 스트림)으로 사용하기위한 몇 가지 방법이 더 포함되어 있습니다.


답변

커먼즈를 사용할 필요가 없음 –Sun은 Java와 함께 base64 인코더를 제공합니다. 다음과 같이 가져올 수 있습니다.

import sun.misc.BASE64Decoder;

그런 다음 다음과 같이 사용하십시오.

BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);

encodedBytesa java.lang.String또는 a 는 어디에 있습니까 java.io.InputStream? sun.*Sun 이 클래스를 “공식적으로 지원하지”않도록 주의하십시오 .

편집 : 이것이 내가 게시 한 가장 논란의 여지가 될 것이라는 것을 누가 알았습니까? 나는 sun. * 패키지가 기존을 계속 지원할 수 없다는 것을 알고 있으며, Commons에 대해 알고 항상 사용합니다. 그러나 포스터는 “Sun Java 6에 포함 된”클래스를 요청했으며 이것이 바로 대답하려는 것입니다. 나는 Commons가 일반적으로가는 가장 좋은 방법이라는 데 동의합니다.

편집 2 : amir75가 아래에서 지적한 것처럼 Java 6 이상에는 Base64를 인코딩 / 디코딩하는 지원 코드가 포함 된 JAXB가 제공됩니다. 참조하시기 바랍니다 제레미 로스 ‘대답 하기를.


답변

특히에 커먼즈 코덱 : 클래스 Base64decode(byte[] array)또는encode(byte[] array)


답변

구아바에는 Base64 디코딩 기능이 내장되어 있습니다.

사용 BaseEncoding.base64 (). 디코딩 ()

입력 사용시 가능한 공백 처리

BaseEncoding.base64().decode(CharMatcher.WHITESPACE.removeFrom(...));

자세한 내용은 이 토론 을 참조하십시오


답변

내 솔루션이 가장 빠르고 쉽습니다.

public class MyBase64 {

    private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

    private static int[]  toInt   = new int[128];

    static {
        for(int i=0; i< ALPHABET.length; i++){
            toInt[ALPHABET[i]]= i;
        }
    }

    /**
     * Translates the specified byte array into Base64 string.
     *
     * @param buf the byte array (not null)
     * @return the translated Base64 string (not null)
     */
    public static String encode(byte[] buf){
        int size = buf.length;
        char[] ar = new char[((size + 2) / 3) * 4];
        int a = 0;
        int i=0;
        while(i < size){
            byte b0 = buf[i++];
            byte b1 = (i < size) ? buf[i++] : 0;
            byte b2 = (i < size) ? buf[i++] : 0;

            int mask = 0x3F;
            ar[a++] = ALPHABET[(b0 >> 2) & mask];
            ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
            ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
            ar[a++] = ALPHABET[b2 & mask];
        }
        switch(size % 3){
            case 1: ar[--a]  = '=';
            case 2: ar[--a]  = '=';
        }
        return new String(ar);
    }

    /**
     * Translates the specified Base64 string into a byte array.
     *
     * @param s the Base64 string (not null)
     * @return the byte array (not null)
     */
    public static byte[] decode(String s){
        int delta = s.endsWith( "==" ) ? 2 : s.endsWith( "=" ) ? 1 : 0;
        byte[] buffer = new byte[s.length()*3/4 - delta];
        int mask = 0xFF;
        int index = 0;
        for(int i=0; i< s.length(); i+=4){
            int c0 = toInt[s.charAt( i )];
            int c1 = toInt[s.charAt( i + 1)];
            buffer[index++]= (byte)(((c0 << 2) | (c1 >> 4)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c2 = toInt[s.charAt( i + 2)];
            buffer[index++]= (byte)(((c1 << 4) | (c2 >> 2)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c3 = toInt[s.charAt( i + 3 )];
            buffer[index++]= (byte)(((c2 << 6) | c3) & mask);
        }
        return buffer;
    }

}


답변

누군가에게 유용 할 수 있다면 내 자신의 구현이 있습니다.

public class Base64Coder {

    // The line separator string of the operating system.
    private static final String systemLineSeparator = System.getProperty("line.separator");

    // Mapping table from 6-bit nibbles to Base64 characters.
    private static final char[] map1 = new char[64];
       static {
          int i=0;
          for (char c='A'; c<='Z'; c++) map1[i++] = c;
          for (char c='a'; c<='z'; c++) map1[i++] = c;
          for (char c='0'; c<='9'; c++) map1[i++] = c;
          map1[i++] = '+'; map1[i++] = '/'; }

    // Mapping table from Base64 characters to 6-bit nibbles.
    private static final byte[] map2 = new byte[128];
       static {
          for (int i=0; i<map2.length; i++) map2[i] = -1;
          for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }

    /**
    * Encodes a string into Base64 format.
    * No blanks or line breaks are inserted.
    * @param s  A String to be encoded.
    * @return   A String containing the Base64 encoded data.
    */
    public static String encodeString (String s) {
       return new String(encode(s.getBytes())); }

    /**
    * Encodes a byte array into Base 64 format and breaks the output into lines of 76 characters.
    * This method is compatible with <code>sun.misc.BASE64Encoder.encodeBuffer(byte[])</code>.
    * @param in  An array containing the data bytes to be encoded.
    * @return    A String containing the Base64 encoded data, broken into lines.
    */
    public static String encodeLines (byte[] in) {
       return encodeLines(in, 0, in.length, 76, systemLineSeparator); }

    /**
    * Encodes a byte array into Base 64 format and breaks the output into lines.
    * @param in            An array containing the data bytes to be encoded.
    * @param iOff          Offset of the first byte in <code>in</code> to be processed.
    * @param iLen          Number of bytes to be processed in <code>in</code>, starting at <code>iOff</code>.
    * @param lineLen       Line length for the output data. Should be a multiple of 4.
    * @param lineSeparator The line separator to be used to separate the output lines.
    * @return              A String containing the Base64 encoded data, broken into lines.
    */
    public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) {
       int blockLen = (lineLen*3) / 4;
       if (blockLen <= 0) throw new IllegalArgumentException();
       int lines = (iLen+blockLen-1) / blockLen;
       int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length();
       StringBuilder buf = new StringBuilder(bufLen);
       int ip = 0;
       while (ip < iLen) {
          int l = Math.min(iLen-ip, blockLen);
          buf.append (encode(in, iOff+ip, l));
          buf.append (lineSeparator);
          ip += l; }
       return buf.toString(); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in  An array containing the data bytes to be encoded.
    * @return    A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in) {
       return encode(in, 0, in.length); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in    An array containing the data bytes to be encoded.
    * @param iLen  Number of bytes to process in <code>in</code>.
    * @return      A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in, int iLen) {
       return encode(in, 0, iLen); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in    An array containing the data bytes to be encoded.
    * @param iOff  Offset of the first byte in <code>in</code> to be processed.
    * @param iLen  Number of bytes to process in <code>in</code>, starting at <code>iOff</code>.
    * @return      A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in, int iOff, int iLen) {
       int oDataLen = (iLen*4+2)/3;       // output length without padding
       int oLen = ((iLen+2)/3)*4;         // output length including padding
       char[] out = new char[oLen];
       int ip = iOff;
       int iEnd = iOff + iLen;
       int op = 0;
       while (ip < iEnd) {
          int i0 = in[ip++] & 0xff;
          int i1 = ip < iEnd ? in[ip++] & 0xff : 0;
          int i2 = ip < iEnd ? in[ip++] & 0xff : 0;
          int o0 = i0 >>> 2;
          int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
          int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
          int o3 = i2 & 0x3F;
          out[op++] = map1[o0];
          out[op++] = map1[o1];
          out[op] = op < oDataLen ? map1[o2] : '='; op++;
          out[op] = op < oDataLen ? map1[o3] : '='; op++; }
       return out; }

    /**
    * Decodes a string from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param s  A Base64 String to be decoded.
    * @return   A String containing the decoded data.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static String decodeString (String s) {
       return new String(decode(s)); }

    /**
    * Decodes a byte array from Base64 format and ignores line separators, tabs and blanks.
    * CR, LF, Tab and Space characters are ignored in the input data.
    * This method is compatible with <code>sun.misc.BASE64Decoder.decodeBuffer(String)</code>.
    * @param s  A Base64 String to be decoded.
    * @return   An array containing the decoded data bytes.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decodeLines (String s) {
       char[] buf = new char[s.length()];
       int p = 0;
       for (int ip = 0; ip < s.length(); ip++) {
          char c = s.charAt(ip);
          if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
             buf[p++] = c; }
       return decode(buf, 0, p); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param s  A Base64 String to be decoded.
    * @return   An array containing the decoded data bytes.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (String s) {
       return decode(s.toCharArray()); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param in  A character array containing the Base64 encoded data.
    * @return    An array containing the decoded data bytes.
    * @throws    IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (char[] in) {
       return decode(in, 0, in.length); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param in    A character array containing the Base64 encoded data.
    * @param iOff  Offset of the first character in <code>in</code> to be processed.
    * @param iLen  Number of characters to process in <code>in</code>, starting at <code>iOff</code>.
    * @return      An array containing the decoded data bytes.
    * @throws      IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (char[] in, int iOff, int iLen) {
       if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
       while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--;
       int oLen = (iLen*3) / 4;
       byte[] out = new byte[oLen];
       int ip = iOff;
       int iEnd = iOff + iLen;
       int op = 0;
       while (ip < iEnd) {
          int i0 = in[ip++];
          int i1 = in[ip++];
          int i2 = ip < iEnd ? in[ip++] : 'A';
          int i3 = ip < iEnd ? in[ip++] : 'A';
          if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int b0 = map2[i0];
          int b1 = map2[i1];
          int b2 = map2[i2];
          int b3 = map2[i3];
          if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int o0 = ( b0       <<2) | (b1>>>4);
          int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
          int o2 = ((b2 &   3)<<6) |  b3;
          out[op++] = (byte)o0;
          if (op<oLen) out[op++] = (byte)o1;
          if (op<oLen) out[op++] = (byte)o2; }
       return out; }

    // Dummy constructor.
    private Base64Coder() {}
}