Série 6 - Décorateurs d'entrée/sortie base64

Introduction

Lorsque l'e-mail a été inventé, il était uniquement destiné à la transmission de messages textuels en anglais. Dès lors, les messages étaient composés des 26 lettres de l'alphabet latin, des 10 chiffres et de quelques signes de ponctuation.

Ce format n'est bien entendu pas adapté à la transmission de données binaires. Il a dès lors fallu trouver un moyen d'encoder de telles données et de les transformer en une séquence de caractères.

L'encodage base64 permet justement de faire cela. Son idée est d'encoder chaque séquence de 6 bits au moyen d'une lettre parmi 64. Par exemple, la séquence 00000 est encodée par le caractère A majuscule, la séquence 00001 par le caractère B majuscule, etc. En plus des 26 lettres majuscules, des 26 lettres minuscules et des dix chiffres, les caractères + et / sont également utilisés. Finalement, le caractère = est utilisé comme valeur de bourrage (padding) comme nous le verrons.

La table de correspondance complète entre les caractères et les séquences de bits est donnée sur la page Wikipedia, de même qu'une bonne explication de l'encodage.

Le but de cette série est d'écrire des décorateurs pour les flots d'entrée et de sortie Java qui encodent et décodent un flot sous-jacent au format base64.

Décorateur d'entrée base64

Ecrivez une classe Base64InputStream qui hérite de java.io.InputStream et décore un flot d'entrée quelconque en se chargeant de transformer les données qu'il fournit, qui doivent être encodées en base64, en données binaires.

Votre classe doit redéfinir les méthodes read et close. La méthode read doit se charger du décodage des données obtenues du flot décoré, tandis que la méthode close doit fermer le flot décoré. La méthode read doit lever l'exception IOException si le flot sous-jacent produit une valeur qui n'est pas valide selon l'encodage base64.

Pensez à bien traiter le cas où le flot décoré n'a plus de données à fournir, ce qu'il signale en retournant -1 lors d'un appel à read.

Pour tester cette classe, vous pouvez l'appliquer à la chaîne suivante et afficher le résultat. Vous devriez obtenir un court texte.

TnVsIG4nZXN0IHBsdXMgZXNjbGF2ZSBxdWUgY2VsdWkgcXVpIHNlIGNyb2l0IGxpYnJlIHNhbnMgbCdldHJlLgogIC0tIEpvaGFubiBXb2xmZ2FuZyB2b24gR29ldGhl

Décorateur de sortie base64

Ecrivez une classe Base64OutputStream qui hérite de java.io.OutputStream et décore un flot de sortie quelconque en se chargeant d'encoder les données binaires reçues en base64 avant de les envoyer au flot décoré.

Votre classe doit redéfinir les méthodes write et close. La méthode write doit encoder les données reçues avant de les envoyer au flot décoré, tandis que la méthode close doit fermer le flot décoré en pensant à y écrire auparavant les données qui resteraient encore.

En effet, il est possible que le nombre de bits écrits dans votre flot avant l'appel à close ne soit pas un mutiple de 6, auquel cas il reste encore des données à écrire. Dans ce cas, on ajoute simplement des bits 0 à la fin pour arriver à un multiple de 6.

Finalement, gérez le bourrage. L'idée du bourrage est de s'assurer que le nombre de bits produits est un multiple de 24. Cela n'est pas strictement nécessaire, mais exigé par la norme néanmoins. Ce bourrage se fait en ajoutant un ou deux caractères = à la fin du flot pour arriver à une longueur totale qui soit un multiple de 24.

Pour testez votre classe, utilisez-la pour encoder les chaines suivantes en vérifiant que vous obtenez le résultat attendu :

ChaîneEncodage
bYg==
baYmE=
basYmFz
baseYmFzZQ==
base64YmFzZTY0
base64!YmFzZTY0IQ==
Michel Schinz – 2013-04-25 21:59