Encodage et décodage Java Base64

1. Vue d'ensemble

Dans ce didacticiel, nous explorons les différents utilitaires qui fournissent des fonctionnalités d'encodage et de décodage Base64 en Java.

Nous allons principalement illustrer les nouvelles API Java 8 et les API utilitaires qui sortent d'Apache Commons.

2. Java 8 pour Base 64

Java 8 a enfin ajouté des fonctionnalités Base64 à l'API standard. Cela se fait via la classe utilitaire java.util.Base64 .

Commençons par examiner un processus d'encodeur de base.

2.1. Java 8 Basic Base64

L'encodeur de base simplifie les choses et encode l'entrée telle quelle, sans aucune séparation de ligne.

La sortie est mappée à un jeu de caractères dans le jeu de caractères A-Za-z0-9 + / , et le décodeur rejette tout caractère en dehors de ce jeu.

Commençons par encoder une chaîne simple :

String originalInput = "test input"; String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes()); 

Notez comment nous récupérons l' API Encoder complète via la méthode simple de l' utilitaire getEncoder () .

Décodons maintenant cette chaîne à sa forme d'origine:

byte[] decodedBytes = Base64.getDecoder().decode(encodedString); String decodedString = new String(decodedBytes);

2.2. Encodage Java 8 Base64 sans remplissage

Dans le codage Base64, la longueur de la chaîne codée en sortie doit être un multiple de trois. Sinon, la sortie sera complétée avec des caractères de pad supplémentaires ( = ).

Lors du décodage, ces caractères de remplissage supplémentaires seront supprimés. Pour approfondir le rembourrage en Base64, consultez cette réponse détaillée sur Stack Overflow.

Si nous devons ignorer le remplissage de la sortie - peut-être parce que la chaîne résultante ne sera jamais décodée à nouveau - nous pouvons simplement choisir d' encoder sans remplissage :

String encodedString = Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());

2.3. Encodage d'URL Java 8

Le codage d'URL est très similaire à l'encodeur de base que nous avons examiné ci-dessus. Il utilise l'alphabet URL et nom de fichier Safe Base64 et n'ajoute aucune séparation de ligne:

String originalUrl = "//www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java"; String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes()); 

Le décodage se produit à peu près de la même manière. La méthode utilitaire getUrlDecoder () renvoie un java.util.Base64.Decoder qui est ensuite utilisé pour décoder l'URL:

byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl); String decodedUrl = new String(decodedBytes); 

2.4. Encodage MIME Java 8

Commençons par générer une entrée MIME de base à encoder:

private static StringBuilder getMimeBuffer() { StringBuilder buffer = new StringBuilder(); for (int count = 0; count < 10; ++count) { buffer.append(UUID.randomUUID().toString()); } return buffer; }

L'encodeur MIME génère une sortie encodée en Base64 en utilisant l'alphabet de base mais dans un format compatible MIME.

Chaque ligne de la sortie ne dépasse pas 76 caractères et se termine par un retour chariot suivi d'un saut de ligne ( \ r \ n ):

StringBuilder buffer = getMimeBuffer(); byte[] encodedAsBytes = buffer.toString().getBytes(); String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);

La méthode de l'utilitaire getMimeDecoder () renvoie un java.util.Base64.Decoder qui est ensuite utilisé dans le processus de décodage:

byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime); String decodedMime = new String(decodedBytes); 

3. Encodage / décodage à l'aide du code Apache Commons

Tout d'abord, nous devons définir la dépendance commons-codec dans le pom.xml :

 commons-codec commons-codec 1.10 

Notez que nous pouvons vérifier si des versions plus récentes de la bibliothèque ont été publiées sur Maven Central.

L'API principale est la classe org.apache.commons.codec.binary.Base64 , qui peut être paramétrée avec différents constructeurs:

  • Base64 (boolean urlSafe) crée l'API Base64 en contrôlant le mode de sécurité URL - activé ou désactivé.
  • Base64 (int lineLength) crée l'API Base64 dans un mode URL non sécurisé et contrôle la longueur de la ligne (la valeur par défaut est 76).
  • Base64 (int lineLength, byte [] lineSeparator) crée l'API Base64 en acceptant un séparateur de ligne supplémentaire, qui par défaut est CRLF («\ r \ n»).

Une fois l'API Base64 créée, l'encodage et le décodage sont assez simples:

String originalInput = "test input"; Base64 base64 = new Base64(); String encodedString = new String(base64.encode(originalInput.getBytes())); 

La méthode decode () de la classe Base64 renvoie la chaîne décodée:

String decodedString = new String(base64.decode(encodedString.getBytes())); 

Une autre option simple consiste à utiliser l'API statique de Base64 au lieu de créer une instance:

String originalInput = "test input"; String encodedString = new String(Base64.encodeBase64(originalInput.getBytes())); String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));

4. Conversion d'une chaîne en tableau d' octets

Parfois, nous devons convertir une chaîne en octet [] . Le moyen le plus simple de le faire est d'utiliser la méthode String getBytes () :

String originalInput = "test input"; byte[] result = originalInput.getBytes(); assertEquals(originalInput.length(), result.length);

It's better to provide encoding as well and not depend on default encoding, as it's system dependent:

String originalInput = "test input"; byte[] result = originalInput.getBytes(StandardCharsets.UTF_16); assertTrue(originalInput.length() < result.length);

If our String is Base64 encoded, we can use the Base64 decoder:

String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = Base64.getDecoder().decode(originalInput); assertEquals("test input", new String(result));

We can also use DatatypeConverter parseBase64Binary() method:

String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = DatatypeConverter.parseBase64Binary(originalInput); assertEquals("test input", new String(result));

Finally, we can convert a hexadecimal String to a byte[] using DatatypeConverter method:

String originalInput = "7465737420696E707574"; byte[] result = DatatypeConverter.parseHexBinary(originalInput); assertEquals("test input", new String(result));

5. Conclusion

This article explained the basics of how to do Base64 encoding and decoding in Java using the new APIs introduced in Java 8 and Apache Commons.

Enfin, il existe quelques autres API à mentionner qui fournissent des fonctionnalités similaires: java.xml.bind.DataTypeConverter avec printHexBinary et parseBase64Binary .

Des extraits de code sont disponibles à l'adresse over sur GitHub.