Outils pour utilisateurs

Outils du site


encodage

Petites contributions à la compréhension des encodages

Essais réalisés avec Python 2.6

Objectif

Depuis le temps que je me cogne (comme tant d'autres) contre les subtilités de l'encodage des chaines de caractères, j'ai investi un peu de temps pour y voir plus clair.

L'objectif de cette page est d'identifier les principes de traitement à utiliser pour intégrer, manipuler, afficher et enregistrer des chaines de caractères comportant, par exemple, des caractères accentués.

A noter que des erreurs de traitement sur ce sujet peuvent aller jusqu'à planter un programme!

Les polices de caractères

L'ordinateur, qui est très bête, ne sait pas ce qu'est un caractère comme “A”. Il ne sait que contenir des codes numériques comme 65 (ou 0x41 en hexa). Le fait de rattacher le nombre 65 à la lettre “A” n'est qu'une convention.

Ainsi, au départ de l'informatique, il a été établi une liste de correspondance très simple, qui ne comportait que:

  • des caractères latins non accentués: a, b, c,…, A, B, C, …
  • des chiffres: 0, 1, …, 9
  • des caractères de ponctuation: !, ?, :, espace, …
  • des caractères de contrôle non imprimables: tabulation, retour chariot, effacement, échappement, …

Cette liste de correspondance, associant un nombre au dessin d'un caractère, ne nécessitait seulement que des nombres de 0 à 127, soit des octets (8 bits) sans le dernier bit de gauche. On parle de codage “ASCII” (http://fr.wikipedia.org/wiki/ASCII).

Elle a été complétée plus tard pour contenir des caractères supplémentaires comme les caractères accentués “é”, “è”, “ô”, …, ainsi que d'autres caractères de contrôle… Mais là, il a fallu étendre les nombres pour utiliser la partie 128 à 255 des octets.

En fait, il y a actuellement de nombreuses normes pour représenter les caractères particuliers des pays, tout en restant à l'intérieur des octets (0 à 255). Les principaux pour nous pays de langue française sont:

L'avantage est que les premiers caractères de 0 à 127 sont sensiblement les mêmes que dans le codage ASCII. Pour les caractères supplémentaires, il y a cependant quelques différences dont il faut se méfier. Par exemple entre cp1252/ANSI et iso-8859-1 :http://www.alanwood.net/demos/charsetdiffs.html.

Pour les autres pays ayant des caractères non latins, il existe d'autres codages de caractères comme l'iso-8859-5 pour l'alphabet cyrillique, l'iso-8859-7 pour l'alphabet grec moderne, etc…


Mais maintenant, comment faire pour que les mêmes programmes puissent, sans changer d'encodage de caractères, être utilisés en Grèce, en Inde, en Russie, en Chine, etc… Ceci d'autant plus qu'avec Internet, les échanges sont devenus quotidiens, et rien ne doit vous empêcher de converser par mail avec des chinois ou des russes. La multiplicité des caractères exclut qu'on reste à l'intérieur des octets (0 à 255): alors, comment on fait? On invente l'UNICODE! Voir http://fr.wikipedia.org/wiki/Unicode.

Il y a en fait plusieurs types d'unicode: UCS-2, UTF-8, UTF-16, UTF-32, …

En simplifiant, pour nous, français utilisant Python:

  • UCS-2 est l'Unicode utilisé en interne par Python. Il est proche de l'UTF-16.
  • UTF-8 utilise de 1 à 4 octets par caractère. L'avantage est que les caractères codés en 1 seul octet de 0 à 127 sont sensiblement les mêmes que dans l'ASCII.
  • UTF-16 utilise 2 octets par caractères (plus si nécessaire pour des cas spéciaux et rares)
  • UTF-32 plus rare, utilise 4 octets par caractères

Généralités sur l'encodage des caractères dans Python

Avec Python 2.6, on peut toujours travailler avec des codages sur un octets, par exemple avec l'iso-8859-1/latin-1 (ou cp1252 sous Windows), mais on va de plus en plus travailler en Unicode. Et ceci, surtout si on travaille en multiplateforme et en multilingue. En ce qui me concerne, comme je fais le plus souvent du développement windows-linux, je suis obligé de travailler le plus souvent en utf-8, y compris pour les codes sources, qui est l'encodage par défaut des Linux modernes.

Les codages utilisables par Python sont ici: http://docs.python.org/library/codecs.html#standard-encodings


Si on veut travailler en Unicode avec Python, voici quelques principes simples à respecter:

  • Dans les traitements, on travaille uniquement en Unicode interne (qui n'est ni l'utf-8 ni l'utf-16!)
  • On convertit le plus tôt possible tout ce qui rentre: saisie, code source, lecture d'un fichier de données ou d'une base de données, réception d'un réseau, etc…
  • On convertit le plus tard possible tout ce qui sort (affichage, impression, écriture dans un fichier de données ou dans une base de données, émission vers un réseau, etc…


Remarques:

  • au fil des dernières versions de Python, il est de plus en plus facile de travailler en Unicode, mais ce n'est encore pas parfait. Par exemple, je ne suis pas sûr que tous les modules Python, et surtout les modules tiers, supportent l'Unicode (il faut vérifier dans le manuel ou dans le code source du module). En tout cas, il ne faut pas utiliser le module string qui est obsolète.
  • la nécessité de convertir en entrée et en sortie suppose que vous avez connaissance des encodages utilisés dans les données externes! Ce n'est pas le plus simple.


Pour reproduire les tests ci-dessous, je vous suggère de vous munir de 3 outils supplémentaires:

  • un éditeur de texte sachant enregistrer sous différents encodages, y compris l'utf-8 (pour Windows, le bloc-note “notepad” fait cela).
  • un éditeur hexadécimal permettant de lire des fichiers (ça existe sous Windows et sous Linux)
  • une table des caractères (ça existe sous Windows et sous Linux)

En ce qui concerne le développement multiplateforme sous Windows, la 1ère difficulté est de trouver un outil de développement qui permette l'édition du code source en UTF-8, ainsi que les fins de ligne UNIX. En ce qui me concerne, j'utilise “Easy Eclipse pour Python”. L'éditeur Scite marche aussi. Mais, par exemple, l'éditeur de texte Context, que j'utilisais beaucoup, ne le permet pas.

Entrée/sortie de chaines de caractères

Chaines de caractères intégrées dans le code source

Quand vous écrivez le code d'un programme, vous utilisez un éditeur de texte qui utilise un encodage vous permettant, par exemple, d'insérer une chaine de caractère comportant des caractères accentués. Quand vous enregistrez le code sur disque, vous devez pouvoir choisir l'encodage utilisé dans l'enregistrement (ou, au moins, le connaitre). Et, pour renseigner python lors de l'exécution, vous devez l'informer de l'encodage du fichier en écrivant la ligne suivante tout au début du code juste après le shebang. Par exemple avec l'encodage “utf-8”:

# -*- coding: utf-8 -*-

Pour comprendre la liaison entre ces éléments, vous pouvez faire les manips suivantes:

Entrées au clavier de chaines de caractères

Entrée par lecture de données sur disque

Conversion interne en unicode

encodage.txt · Dernière modification: 2009/08/31 23:20 par tyrtamos

Outils de la page