Encodage en Base64 dans Java
J'ai besoin d'encoder des données dans l'encodage Base64 en Java. Comment je fais ça? Quel est le nom de la classe qui fournit un encodeur Base64?
J'ai essayé d'utiliser la classe Sun.misc.BASE64Encoder
, sans succès. J'ai la ligne suivante de code Java 7:
wr.write(new Sun.misc.BASE64Encoder().encode(buf));
J'utilise Eclipse. Eclipse marque cette ligne comme une erreur. J'ai importé les bibliothèques requises:
import Sun.misc.BASE64Encoder;
import Sun.misc.BASE64Decoder;
Mais encore une fois, les deux sont présentés comme des erreurs. J'ai trouvé n post similaire ici .
J'ai utilisé Apache Commons comme solution suggérée en incluant:
import org.Apache.commons.*;
et importer les fichiers JAR téléchargés à partir de: http://commons.Apache.org/codec/
Mais le problème existe toujours. Eclipse affiche toujours les erreurs mentionnées précédemment. s'il vous plaît donnez votre avis.
Vous devez modifier l’import de votre classe:
import org.Apache.commons.codec.binary.Base64;
Et puis changez votre classe pour utiliser la classe Base64.
Voici un exemple de code:
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));
Ensuite, lisez pourquoi vous ne devriez pas utiliser les packages Sun. * .
Mise à jour (16/12/2016)
Vous pouvez maintenant Java.util.Base64
avec Java8. D'abord, importez-le comme vous le faites normalement:
import Java.util.Base64;
Ensuite, utilisez les méthodes statiques Base64 comme suit:
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));
Si vous voulez directement encoder une chaîne et obtenir le résultat sous forme de chaîne encodée, vous pouvez l'utiliser.
String encodeBytes = Base64.getEncoder().encodeToString((userName + password).getBytes());
Voir Javadocs pour Base64 pour plus d'informations: https://docs.Oracle.com/javase/8/docs/api/Java/util/Base64.html
Utilisez la classe jamais-trop-tard-à-rejoindre-dans-le-fun de Java 8: Java.util.Base64
Vous pouvez également convertir en utilisant l’encodage base64. Pour ce faire, vous pouvez utiliser la méthode javax.xml.bind.DatatypeConverter#printBase64Binary
Par exemple:
_byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));
_
Dans Java 8, cela peut être fait comme
Base64.getEncoder().encodeToString(string.getBytes(StandardCharsets.UTF_8))
Voici un exemple complet court et complet
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);
}
}
donne la sortie
old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==
Google Guava est un autre choix pour coder et décoder des données en base64:
configuration POM:
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>14.0.1</version>
</dependency>
Exemple de code:
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
Eclipse vous signale une erreur/un avertissement parce que vous essayez d'utiliser des classes internes spécifiques à un fournisseur JDK et ne faisant pas partie de l'API publique. Jakarta Commons fournit sa propre implémentation de codecs base64, qui, bien sûr, résident dans un paquet différent. Supprimez ces importations et laissez Eclipse importer les classes Commons appropriées pour vous.
Pour Java 6-7, la meilleure option consiste à emprunter le code du référentiel Android. Il n'a pas de dépendances.
https://github.com/Android/platform_frameworks_base/blob/master/core/Java/Android/util/Base64.Java
Sous Android, utilisez les méthodes statiques de la classe d'utilitaire Android.util.Base64 . La documentation référencée indique que la classe Base64 a été ajoutée dans l'API de niveau 8 (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));
Pour convertir cela, vous avez besoin d'un encodeur et d'un décodeur que vous obtiendrez de http://www.source-code.biz/base64coder/Java/ . C'est le fichier Base64Coder.Java vous en aurez besoin.
Maintenant, pour accéder à cette classe selon vos besoins, vous aurez besoin de la classe ci-dessous:
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);
}
}
}
Dans Android, vous pouvez convertir votre bitmap en Base64 pour le téléchargement sur le serveur/service Web.
Bitmap bmImage = //Data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageData = baos.toByteArray();
String encodedImage = Base64.encodeArray(imageData);
Cette "image codée" est une représentation textuelle de votre image. Vous pouvez l'utiliser pour le téléchargement ou pour l'affichage directement dans une page HTML comme ci-dessous ( 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" />
Documentation: http://dwij.co.in/Java-base64-image-encoder
Voici mes deux cents ... Java 8 contient sa propre implémentation de Base64
. Cependant, j'ai trouvé une différence légèrement dérangeante. Pour illustrer cela, je vais donner un exemple de code:
Mon 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 test:
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));
}
}
OUTPUT:
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)
Notez que le texte codé Apache contient des sauts de ligne supplémentaires (espaces blancs) à la fin. Par conséquent, pour que mon CODEC produise le même résultat quelle que soit l'implémentation Base64, je devais appeler trim()
sur le texte codé Apache. Dans mon cas, j’ai simplement ajouté l’appel de méthode susmentionné à la apacheDecode()
de mon CODEC comme suit:
return Base64.encodeBase64String(decodedByteArr).trim();
Une fois que ce changement a été effectué, les résultats sont ceux avec lesquels je m'attendais:
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!
Peut-être que quelqu'un pourrait expliquer pourquoi, mais j'ai trouvé ma solution de contournement comme un compromis acceptable.
Apache commons a la bonne implémentation de base64. vous pouvez le faire aussi simplement que
// 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));
vous pouvez trouver plus de détails sur l'encodage en base64 à l'adresse http://faisalbhagat.blogspot.com/2014/06/base64-encoding-using-Java-and.html
Si vous utilisez au moins la version 4.1 de Spring Framework, vous pouvez utiliser org.springframework.util.Base64Utils class:
byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);
Il déléguera à Java 8 Base64, Apache Commons Codec ou JAXB DatatypeConverter, selon les disponibilités.
Exemple simple avec Java 8:
import Java.util.Base64;
String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
Si vous êtes bloqué sur une version antérieure de Java supérieure à 8 mais que vous utilisez déjà AWS SDK pour Java , vous pouvez utiliser com.amazonaws.util.Base64 .
Dans Java 7 j'ai codé cette méthode
import javax.xml.bind.DatatypeConverter;
public static String toBase64(String data) {
return DatatypeConverter.printBase64Binary(data.getBytes());
}
J'ai essayé avec l'extrait de code suivant. Cela a bien fonctionné :-)
com.Sun.org.Apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");