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îne | Encodage |
---|---|
b | Yg== |
ba | YmE= |
bas | YmFz |
base | YmFzZQ== |
base64 | YmFzZTY0 |
base64! | YmFzZTY0IQ== |