Codificação Base64 em Java

Eu estou usando o Eclipse. Eu tenho a seguinte linha de código:

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

O Eclipse marca esta linha como um erro. Eu importei as bibliotecas necessárias:

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

Mas, novamente, ambos são mostrados como erros. Eu encontrei um post semelhante aqui .

Eu usei o Apache Commons como a solução sugerida, incluindo:

 import org.apache.commons.*; 

e importando os arquivos JAR baixados de: http://commons.apache.org/codec/

Mas o problema ainda existe. O Eclipse ainda mostra os erros mencionados anteriormente; Por favor informar.

Você precisa alterar a importação da sua class:

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

E então mude sua class para usar a class Base64.

Aqui está um código de exemplo:

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

Então leia por que você não deve usar pacotes sun * .


Atualização (16/12/2016)

Você pode agora java.util.Base64 com Java8. Primeiro, importe-o como você faz normalmente:

 import java.util.Base64; 

Em seguida, use os methods estáticos Base64 da seguinte maneira:

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

Veja Javadocs for Base64 para mais: https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html

Use a class “nunca é tarde demais para entrar na diversão” do Java 8: java.util.Base64

Você também pode converter usando codificação base64. Para fazer isso, você pode usar o método javax.xml.bind.DatatypeConverter#printBase64Binary

Por exemplo:

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

No Java 8, isso pode ser feito

 Base64.getEncoder().encodeToString(string.getBytes(StandardCharsets.UTF_8)) 

Aqui está um exemplo completo, pequeno e independente

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

dá saída

 old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw== 

O Google Guava é uma boa opção para codificar e decodificar dados base64:

Configuração do POM:

  guava com.google.guava jar 14.0.1  

Código de amostra:

 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 

O Eclipse fornece um erro / aviso porque você está tentando usar classs internas que são específicas de um fornecedor do JDK e não fazem parte da API pública. O Jakarta Commons fornece sua própria implementação de codecs base64, que naturalmente residem em um pacote diferente. Exclua essas importações e deixe o Eclipse importar as classs apropriadas do Commons para você.

Para converter isso, você precisa do codificador e decodificador que você obterá em http://www.source-code.biz/base64coder/java/ . É o arquivo Base64Coder.java que você irá precisar.

Agora, para acessar essa class conforme sua necessidade, você precisará de uma class abaixo:

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

No Android, você pode converter seu Bitmap em Base64 para Upload para Servidor / Serviço da Web.

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

Este “encodedImage” é uma representação de texto da sua imagem. Você pode usar isso para fins de upload ou para exibição diretamente na Página HTML conforme abaixo ( Referência ):

   

Documentação: http://dwij.co.in/java-base64-image-encoder

Para o java 6-7, a melhor opção é pedir emprestado código do repository do Android. Não tem dependencies.

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

o apache commons tem uma boa implementação de base64. você pode fazer isso tão simples quanto

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

você pode encontrar mais detalhes sobre codificação de base64 em http://faisalbhagat.blogspot.com/2014/06/base64-encoding-using-java-and.html

Aqui estão meus dois centavos … O Java 8 contém sua própria implementação do Base64 . No entanto, encontrei uma diferença ligeiramente perturbadora. Para ilustrar, vou fornecer um exemplo de código:

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

Classe de Teste:

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

SAÍDA:

 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) 

Observe que o texto codificado do Apache contém quebras de linha adicionais (espaços em branco) no final. Portanto, para meu CODEC produzir o mesmo resultado, independentemente da implementação de Base64, tive que chamar trim() no texto codificado do Apache. No meu caso, eu simplesmente adicionei a chamada de método acima mencionada ao apacheDecode() do meu CODEC da seguinte forma:

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

Depois que essa alteração foi feita, os resultados são o que eu esperava começar:

 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! 

Talvez alguém possa comentar por que isso acontece, mas achei minha solução alternativa aceitável.

No Android, use os methods estáticos da class de utilitários android.util.Base64 . A documentação referenciada diz que a class Base64 foi adicionada no nível 8 da API (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)); 

Exemplo simples com o Java 8:

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

Se você estiver usando o framework Spring pelo menos na versão 4.1, você pode usar a class org.springframework.util.Base64Utils :

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

Ele delegará ao Base64 do Java 8, Apache Commons Codec ou JAXB DatatypeConverter, dependendo do que estiver disponível.

Se você estiver preso a uma versão anterior do Java que 8, mas já estiver usando o AWS SDK para Java , poderá usar com.amazonaws.util.Base64 .

No Java 7 eu codifiquei esse método

 import javax.xml.bind.DatatypeConverter; public static String toBase64(String data) { return DatatypeConverter.printBase64Binary(data.getBytes()); } 

Eu tentei com o seguinte trecho de código. Funcionou bem. 🙂

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