Unicode et UTF-8

Un article de Haypo.

Retour à la page précédente Retour à l'accueil des codages

Avertissement

Cet article est en cours de rédaction. Sa qualité est pauvre et son intérêt limité. Revenez un peu plus tard (ça peut être long), et lisez un autre article en attendant ;-) Si vous êtes impatient de lire la suite, secouez un peu son auteur :o)

Cet article présente le standard Unicode et l'encodage UTF-8. J'ai pensé d'abord faire deux articles séparés, mais ils vont tellement bien ensemble que je les ai regroupé dans un seul et même article.

Sommaire

[modifier] Unicode

Unicode est un standard issu de longues années de négociations entre différents pays et organismes de normalisation. Il existe plusieurs versions d'Unicode dont la première date de 1991. En 2005, on en est à la version 4.0 je crois bien, et la plupart des logiciels en sont à la version 3.0. Le standard est composé de plusieurs parties :

  • Association code <=> caractère (partie la plus connue)
  • Décomposition des lettres accentuées en : cararactère de base + suite de diachritiques (super pratique pour faire des recherches plein texte par exemple)
  • Conseils pour l'implémentation
  • Instructions sur l'orientation du texte (gauche à droite, droite à gauche, vertical, etc.)
  • ... (je ne connais pas tout perso)

Unicode se veut stable dans le temps. Le code d'un caractère défini en 1991 sera encore valide en 2005, ou en 2100 :-)

Les caractères Unicode sont organisés par blocs. Exemples de blocs :

  • 0x00 à 0x7F : Latin de base
  • 0x590 à 0x5FF : Hébreu
  • 0x1780 à 0x17FF : Khmer
  • etc.

Pour information, les 256 premiers caractères sont identiques à l'encodage ISO-8859-1 (euh, à vérifier que c'est bien celui-là).

[modifier] UTF-8

[modifier] Introduction

L'UTF-8 est très souvent confondu avec Unicode. Ce n'est pas du tout la même chose ! Unicode est une correspondance entre un caractère et un nombre entier, alors que l'UTF-8 est une représentation informatique des nombres entiers. Plus exactement, l'UTF-8 sert à écrire des chaînes de caractères Unicode sous forme d'une suite d'octet.

[modifier] Encodage

L'encodage UTF-8 est assez simple, mais il est difficile de manipuler des chaînes encodées avec cette méthode. En fait, la longueur d'un caractère varie selon la valeur numérique du caractère :

  • Code tenant sur 7 bits : un octet, 0xxxxxxx
  • Code tenant sur 11 bits : deux octets, 110xxxxx 10xxxxxx
  • Code tenant sur 16 bits : trois octets, 1110xxxx 10xxxxxx 10xxxxxx
  • Code tenant sur 21 bits : quatre octets, 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  • Code tenant sur ... STOP ! Ca suffit déjà 21 bits pour stocker tout Unicode 4.0 !!! Rassurez-vous, ils ont prévus jusqu'à 6 octets pour la suite, ce qui donne comme valeur maximale : 0x7FFFFFFF (pas moins de 2 147 483 647 caractères !).

Où "xxxx..." sont les bits stockant le code.

Le code UTF-8 est très intelligent car on prenant n'importe quel octet dans une longue suite d'octets UTF-8, on peut savoir si on est au début ou à la fin d'un caractère. Si l'octet est de la forme "10xxxxxx", c'est un octet qui compose un caractère, mais par un octet qui débute une caractère. Au contraire, si l'octet est de la forme "0xxxxxxx" ou "11xxxxxx", c'est le début d'un caractère.

[modifier] Autres encodages pour l'Unicode

Il existe d'autres encodages mieux adaptés à certaines situations :

  • UCS-2 : Encodage de taille fixe (16 bits)
  • UCS-4 : Encodage de taille fixe (32 bits), très pratique sur une architecture 32 bits car un caractère a alors la taille d'un mot mémoire, on manipule donc très rapidement les chaînes de caractère.
  • UTF-16 : Même principe que l'UTF-8, un code est découpé en plusieurs parties selon sa taille en bits, mais cette fois par groupe de deux octets (16 bits).
  • UTF-32 : Encodage basé sur le principe de l'UTF-8 et proche de l'UCS-4 à l'heure actuelle (identique?) car il n'existe pas de code Unicode 4.0 de plus de 21 bits.

Étant donné que l'UTF-8 utilise comme atome de base des octets, il n'y pas de problème d'endian (ordre des octets en mémoire), contrairement à l'UTF-16 ou UCS-4 qui demande à faire attention.

[modifier] Exemple en UTF-8

Attention à ne pas tout mélanger. La lettre e accent aigu (é) porte le code 233 dans les encodages iso-8859-1 et Unicode. Pourtant, en UTF-8 on l'écrit "\xC3\xA9" (deux octets), mais le code est le même ! Cela s'explique par le fait que le code s'écrit sur deux octets :

    C3      A9     (hexadécimal)
11000011 10101001  (binaire)
110xxxxx 10xxxxxx  (masque UTF-8)

Attention, tour de magie, si on prend les bits écrits en gras cela donne : 00011101001 ou encore 11101001 ou encore 128+64+32+8+1 ce qui donne 233 (tada!).

[modifier] Programme pour obtenir le charset d'un terminal

Petit programme permettant de lire le charset utilisé dans un terminal :

#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <langinfo.h>

int main()
{
    char *codeset;
    char *saved_locale;
    saved_locale = strdup(setlocale(LC_CTYPE, NULL));
    setlocale(LC_CTYPE, "");
    codeset = nl_langinfo(CODESET);
    if (codeset && *codeset) {
        printf ("Codeset = \"%s\"\n", codeset);
    } else {
        printf("Erreur!\n");
    }
    setlocale(LC_CTYPE, saved_locale);
    free(saved_locale);
    return 0;
}

Je ne sais pas si ce programme fonctionne sur tous les systèmes d'exploitation. Ca fonctionne sous Linux en tout cas.

[modifier] Articles connexes

[modifier] Liens externes