1 1 1 1 1

Pour les développeurs ! Vous en avez marre de ne rien comprendre aux charset, UTF-8, ISO-8859-1...et compagnie ?

Une explication claire et complète des charsets se trouve ici (merci zemax !) :
http://www.envrac.org !! le lien est mort, je vous copie/colle le texte ci-dessous :

.... allez courage.... j'ai compris (enfin !) alors vous pouvez comprendre !

 

Remontons à la base : Le caractère encoding.

Comme toute donnée, une chaine de caractères est "dans l'ordinateur" une suite d'octets de différentes valeurs. Dans son expression la plus simple, chaque valeur d'octet correspond à une lettre (ex: un octet de valeur 65 correspond à un "A"). Comme un octet peut prendre une valeur comprise entre 0 et 255, on a suffisement de valeurs pour décrire l'alphabet (majuscules + minuscules + chiffres + ponctuation). La correspondance (ou table ou charset) "standard" entre octet et caractère correspond à l'encodage ASCII, qui suffit à couvrir l'alphabet anglo-saxon avec des valeurs comprises entre 0 et 127.

En france on a aussi besoin des caractères accentués (éèê etc...); il existe donc un encodage normé avec le même principe 1 octet = 1 caractère qui décrit aussi les caractères français. C'est le codage ISO-8859-1 ou Latin-1, qui étend la table ASCII. Il existe aussi ANSI et ISO-8859-15 qui étendent ISO-8859-1 de quelques caractères comme €.

D'autres langues ne vont par avoir besoin des caractères accentués et vont utiliser les mêmes valeurs d'octet pour décrire d'autres caractères spécifiques (ex. ISO 8859-2 pour l'Europe centrale, ISO 8859-9 pour le turc, etc...). Si on utilise la table turque pour lire un texte français Latin-1, les accents vont être remplacés par des caractères turcs. Les problèmes sont encore pires avec les tables asiatiques...

Unicode encodé UTF-8.

On a donc créé une table "universelle" où tous les caractères existants ou ayant existé ont une valeur correspondante. C'est Unicode. Mais dans ce cas, 1 octet ne suffit plus à décrire l'eventail des valeurs : on doit alors utiliser plusieurs octets consécutifs pour décrire cette valeur. C'est ce à quoi sert l'encodage UTF-8.

Plutôt que de bêtement utiliser un nombre fixe d'octets pour chaque caractères (ex 4 octets par caractère, ce qui produirait des fichiers 4x plus lourds), en encodage UTF-8, un caractère sera codé sur 1 à 4 octets suivant sa valeur dans la table Unicode. Ainsi un "A" reste la valeur 65 codé sur 1 octet, un "é" sera codé sur 2 octets... C'est pour celà que quand vous regardez un "é" encodé en UTF-8 sur 2 octets avec un afficheur qui prend ça pour du Latin-1, vous verrez "é"

Au niveau d'un éditeur de texte

Il faut utiliser un éditeur qui connait UTF-8. L'éditeur doit être capable de lire un texte UTF-8 et de le comprendre comme tel (c'est à dire afficher des "é" et pas des "é"), et il doit être capable d'enregistrer le texte en UTF-8. Heureusement c'est le cas de tous les bons éditeurs. Même Notepad connait UTF-8. Le choix de l'encodage se fait générallement dans les Préférences ou au moment de l'enregistrement du document.

Comment l'éditeur reconnait-il que le texte est en UTF-8 ?
L'éditeur de texte peut marquer un fichier texte comme étant encodé en UTF grâce au BOM (byte order mark) sur les 3 premiers octets du fichiers. Ce BOM a pour but d'indiquer l'ordre des bits dans les encodages UTF-16 et UTF-32 et sert uniquement de "signature" en UTF-8.

Mais comme celà ajoute des octets (qui peuvent donc être pris aussi comme les caractères "ÿþ"), celà entraine à mon avis beaucoup plus de problèmes que de solutions (cf plus loin avec PHP). D'autant que ce BOM n'est pas une obligation ni dans la norme ni pour l'éditeur de texte. En effet un bon éditeur de texte est capable d'analyser le contenu du texte pour determiner s'il est en Latin-1 ou en UTF-8, et doit donner le choix d'enregistrer ou pas un BOM sur les documents.

Et Flash dans tout ça ?

On va commencer par Flash parce que c'est le plus simple car le plus bête :

  • En SWF version 5 et -, tous les textes envoyés et reçus par Flash (loadVariables, XML...) utilisent le codage "basique" du système sur lequel tourne le SWF, donc Latin-1 pour la France.
  • En SWF version 6 et +, tous les textes envoyés et reçus par Flash utilisent le codage UTF-8.
  • On peut forcer un SWF version 6 et + à utiliser le codage du système en utilisant System.useCodepage = true (mais pourquoi vouloir revenir en arrière ?)

Je dis que Flash est le plus bête car Flash applique ces règles absolument sans tenir compte des informations d'encodage contenues dans les fichiers eux-même ou dans les entêtes HTTP (voir plus loin).

Si vous utilisez (j'espère !) des fichiers .as externes pour vos développement Flash, il faut noter que Flash MX s'attend par défaut à avoir des fichiers encodés en Latin-1, ce qui est débile compte tenu des règles précédentes, mais on peut lui préciser que les fichiers sont en UTF-8 en rajoutant sur la première ligne du fichier "//!-- UTF8". Dans ce cas il ne faut pas utiliser de BOM sur le fichier ou Flash MX ne comprendra pas.

Pour Flash MX 2004 et Flash 8, le BOM ne pose plus problème :

  • soit vous utilisez un fichier UTF-8 avec BOM (AS1 et AS2),
  • soit vous utilisez un fichier UTF-8 sans BOM en mettant "//!-- UTF8" sur la première ligne, comme pour Flash MX (AS1 uniquement !),
  • soit vous utilisez un fichier Latin-1.

En (X)HTML/XML ...

Les navigateurs modernes comprennent très bien les différents encodages, l'essentiel est de bien spécifier au navigateur quel est l'encodage utilisé.
Il y a 2 endroits où est décrit l'encodage d'un document (X)HTML ou XML envoyé par un serveur web.

L'un est dans le fichier lui même :

  • c'est un tag méta dans un fichier HTML :
												


  • et c'est un attribut de la déclaration en XML :
												


L'autre est dans l'entête de la réponse HTTP que fait le serveur web quand il envoit le fichier, via l'information charset du Content-Type. C'est donc une information gérée au niveau du serveur. On peut la spécifier pour les scripts PHP avec

												
header ('Content-Type: text/html; charset=utf-8');



mais pour les autres fichiers (en particulier HTML), ça peut poser problème si jamais ce n'est pas la bonne information qui est envoyée, car ce charset a priorité sur celui décrit précedement. Il faut donc vérifier que le serveur Web n'est pas configuré pour renvoyer un charset Latin-1 systématiquement. Le mieux est que le serveur ne renvoie pas de charset, comme ça on peut gérer le charset au niveau du document. Heureusement c'est généralement le cas.

... avec PHP

Il arrive sur Apache que les fichiers PHP aient un charset HTTP déclaré iso-8859-1 par défaut : il est donc préférable de toujours spécifier :