UTF-8 (UCS transformation format 8 bits) est un format de codage de caractères défini pour les caractèresUnicode (UCS). Chaque caractère est codé sur une suite d'un à quatre octets. UTF-8 a été conçu pour être compatible avec certains logiciels originellement prévus pour traiter des caractères d'un seul octet.
UTF-8 est standardisé dans la RFC 3629 (UTF-8, a transformation format of ISO 10646). Le codage était aussi défini dans le rapport technique 17 de la normeUnicode. Il fait maintenant partie intégrante de la norme dans son chapitre 3 Conformance et est également approuvé par l’Organisation internationale de normalisation (ISO), l’Internet Engineering Task Force (IETF) et la plupart des organismes de normalisation nationaux.
Le numéro de chaque caractère est donné par le standardUnicode.
Les caractères de numéro 0 à 127 sont codés sur un octet dont le bit de poids fort est toujours nul.
Les caractères de numéro supérieur à 127 sont codés sur plusieurs octets. Dans ce cas, les bits de poids fort du premier octet forment une suite de 1 de longueur égale au nombre d'octets utilisés pour coder le caractère, les octets suivants ayant 10 comme bits de poids fort.
Définition du nombre d'octets utilisés
Représentation binaire UTF-8
Signification
0xxxxxxx
1 octet codant 1 à 7 bits
110xxxxx 10xxxxxx
2 octets codant 8 à 11 bits
1110xxxx 10xxxxxx 10xxxxxx
3 octets codant 12 à 16 bits
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
4 octets codant 17 à 21 bits
Ce principe pourrait être étendu jusqu'à huit octets pour un caractère, mais UTF-8 pose la limite à quatre. Ce principe permet également d'utiliser plus d'octets que nécessaire pour coder un caractère, mais UTF-8 l'interdit.
Du fait qu'un caractère est découpé en une suite d'octets (et non en mots de plusieurs octets), il n'y a pas de problème d'endianness. Problème qui apparaît avec les codages UTF-16 et UTF-32 par exemple.
Efficacité
Pour les langues utilisant beaucoup les caractères US-ASCII, UTF-8 nécessite moins d'octets que l'UTF-16 ou l'UTF-32.
Réutilisabilité
De nombreuses techniques de programmation informatique valables avec les caractères uniformément codés sur un octet le restent avec UTF-8, notamment :
la manière de repérer la fin d'une chaîne de caractèresC, car l'octet 00000000 dans une chaîne de caractères codés en UTF-8 est toujours le caractère nul.
la manière de trouver une sous-chaîne est identique.
Fiabilité
Il s'agit d'un codage auto-synchronisant (en lisant un seul octet on sait si c'est le premier d'un caractère ou non).
Une séquence décrivant un caractère n'apparaît jamais dans une séquence plus longue décrivant un autre caractère (cas de Shift-JIS).
Il n'existe pas de code « d'échappement » changeant l'interprétation de la suite d'une séquence d'octets.
Inconvénients
Taille variable
Les caractères sont représentés en UTF-8 par des séquences d'octets de taille variable, ce qui rend certaines opérations sur les chaînes de caractères plus compliquées : le calcul du nombre de caractères ; le positionnement à une distance donnée dans un fichier texte et en règle générale toute opération nécessitant l'accès au caractère de position N dans une chaîne.
Efficacité
Pour les langues utilisant beaucoup de caractères extérieurs à US-ASCII, UTF-8 occupe sensiblement plus d'espace. Par exemple, les idéogrammes courants employés dans les textes de langues asiatiques comme le chinois, le coréen ou le japonais (kanji, par exemple) utilisent 3 octets en UTF-8 contre 2 octets en UTF-16. De manière générale, les scripts employant beaucoup de caractères de valeur supérieure à U+0800 occupent plus de mémoire que s'ils étaient codés avec UTF-16.
Séquences invalides
De par son système de codage, il est possible de représenter un point de code de différentes manières en UTF-8, ce qui peut poser un problème de sécurité : un programme mal écrit peut accepter un certain nombre de représentations UTF-8, normalement invalides selon la RFC 3629 mais pas selon la spécification originale, et les convertir comme un seul et même caractère. De fait, un logiciel détectant certaines chaînes de caractères (pour prévenir les injections SQL, par exemple) peut échouer dans sa tâche.
Prenons un exemple tiré d'un cas réel de virus attaquant des serveurs HTTP du Web en 2001 ((en)[1][2][3]). Une séquence à détecter pourrait être « /../ » représentée en ASCII (a fortiori en UTF-8) par les octets « 2F 2E 2E 2F » en notation hexadécimale.
Cependant, une manière malformée de coder cette chaîne en UTF-8 serait « 2F C0 AE 2E 2F », appelée aussi en anglais overlong form (forme superlongue). Si le logiciel n'est pas soigneusement écrit pour rejeter cette chaîne, en la mettant par exemple sous forme canonique, une brèche potentielle de sécurité est ouverte. Cette attaque est appelée directory traversal.
Histoire
UTF-8 a été inventé par Kenneth Thompson lors d'un dîner avec Rob Pike aux alentours de septembre 1992. Il a été immédiatement utilisé dans le système d'exploitationPlan 9 sur lequel ils travaillaient. Une contrainte à résoudre était de coder les caractères nul et '/' comme en ASCII et qu'aucun octet codant un autre caractère n'ait le même code. Ainsi les systèmes d'exploitation UNIX pouvaient continuer à rechercher ces deux caractères dans une chaîne sans adaptation logicielle.
Prise en charge
Navigateurs web : la prise en charge d'UTF-8 commença à être répandue à partir de 1998.
Les anciens navigateurs web ne supportant pas UTF-8 affichent tout de même correctement les 127 premiers caractères ASCII.
(fr)Conformité - Traduction du Standard Unicode en français [pdf]
(en)Conformance - The Unicode Standard 4.0, chapitre 3.2 pp. 60-61 et chapitre 3.4 pp. 64-65 et chapitre 3.9 pp. 73-81, août 2003, ISBN 0-321-18578-1[pdf]
(en)RFC 3629 - UTF-8, a transformation format of ISO 10646, novembre 2003 (standard, totalement compatible avec Unicode) ;
(en)RFC 2279 - UTF-8, a transformation format of ISO 10646, janvier 1998 (ancienne révision, obsolète) ;
(en)RFC 2044 - UTF-8, a transformation format of Unicode and ISO 10646, octobre 1996 (version initiale approuvée par l’ISO, obsolète) ;