118 votes

Comment fonctionne le "codage à largeur variable" UTF-8 ?

La norme Unicode comporte suffisamment de points de code pour qu'il faille 4 octets pour les stocker tous. C'est ce que fait l'encodage UTF-32. Pourtant, le codage UTF-8 les comprime en quelque sorte dans des espaces beaucoup plus petits en utilisant quelque chose appelé "codage à largeur variable".

En fait, il parvient à représenter les 127 premiers caractères de l'US-ASCII en un seul octet qui ressemble exactement au véritable ASCII, de sorte que vous pouvez interpréter beaucoup de texte ascii comme s'il s'agissait d'UTF-8 sans rien y faire. Un bon truc. Comment cela fonctionne-t-il ?

Je vais poser ma propre question et y répondre, car j'ai lu un peu pour trouver la réponse et j'ai pensé que cela pourrait faire gagner du temps à quelqu'un d'autre. De plus, quelqu'un pourra peut-être me corriger si j'ai fait des erreurs.

8 votes

L'Unicode droit fait no nécessite 32 bits pour coder tous ses points de code. Ils ont un jour revendiqué ce nombre de points de code possibles, mais après le décollage de l'UTF-8, ils se sont intentionnellement limités à 21 bits, afin que l'UTF-8 ne dépasse jamais 4 octets par caractère. Unicode ne requiert actuellement que 17 bits pour contenir tous les points de code possibles. Sans cette limitation, UTF-8 aurait pu aller jusqu'à 6 octets par caractère.

0 votes

@Warren : plutôt exact, mais Unicode est un code de 21 bits (U+0000 à U+10FFFF).

2 votes

@Warren : L'UTF-8 limité à 4 octets aurait pu supporter jusqu'à U+1FFFFF. La restriction à U+10FFFF a été faite pour le bien de l'UTF-16.

135voto

dsimard Points 950

Chaque octet commence par quelques bits qui vous indiquent s'il s'agit d'un point de code d'un seul octet, d'un point de code de plusieurs octets ou de la suite d'un point de code de plusieurs octets. Comme ceci :

0xxxxxxx Un code US-ASCII à un octet (parmi les 127 premiers caractères)

Les points de code multi-octets commencent chacun par quelques bits qui disent essentiellement "hé, tu dois aussi lire l'octet suivant (ou deux, ou trois) pour comprendre ce que je suis". Ce sont les suivants :

110xxxxx Un autre octet suit

1110xxxx Deux autres octets suivent

11110xxx Trois autres octets suivent

Enfin, les octets qui suivent ces codes de départ ressemblent tous à ceci :

10xxxxxx Une continuation d'un des caractères multi-octets

Puisque vous pouvez savoir quel type d'octet vous regardez à partir des premiers bits, même si quelque chose est endommagé quelque part, vous ne perdez pas toute la séquence.

15 votes

Il y a plus que cela - parce que l'encodage doit être le plus court possible pour le caractère, ce qui signifie que les octets 0xC0 et 0xC1 ne peuvent pas apparaître dans UTF-8, par exemple ; et, en fait, 0xF5..0xFF non plus. Voir la FAQ UTF-8 à l'adresse unicode.org/faq/utf_bom.html o unicode.org/versions/Unicode5.2.0/ch03.pdf

2 votes

Pourquoi ne pourrait-il pas utiliser un seul caractère pour dire next char is continuation ? Si nous avons un caractère de 3 octets, alors ce sera comme suit : 1xxxxxxx 1xxxxxxx 0xxxxxxx Ainsi, moins d'espace serait gaspillé.

10 votes

@Soaku il fait de l'UTF-8 un code dit "auto-synchronisant". Cela signifie que si, en raison d'erreurs, certaines parties de la séquence sont manquantes, il est possible de le détecter et de supprimer ce qui a été déformé. Si vous lisez un octet qui commence par 10xx et qu'aucun octet de "début" ne le précède, vous pouvez le rejeter car il n'a aucun sens. Si vous aviez un système comme celui que vous avez décrit, et que l'un des premiers octets était perdu, vous pourriez vous retrouver avec un caractère différent, valide, sans aucune indication d'une quelconque erreur. Il sera également facile de localiser le prochain caractère valide et de corriger les octets de "continuation" manquants.

9voto

azheglov Points 3548

RFC3629 - UTF-8, un format de transformation de l'ISO 10646 est l'autorité finale ici et a toutes les explications.

En bref, plusieurs bits de chaque octet de la séquence de 1 à 4 octets codée en UTF-8 représentant un seul caractère sont utilisés pour indiquer s'il s'agit d'un octet de queue, d'un octet de tête et, le cas échéant, combien d'octets suivent. Les bits restants contiennent la charge utile.

1 votes

Ummmm, quel idiot je fais, je pensais que le standard Unicode était l'autorité finale sur UTF-8.

6 votes

La norme Unicode définit l'Unicode lui-même. Elle ne définit pas les diverses méthodes, actuelles et futures, qui peuvent être utilisées pour coder les textes Unicode à des fins diverses (comme le stockage et le transport). UTF-8 est l'une de ces méthodes et la référence ci-dessus renvoie au document qui la définit.

2 votes

RFC3629, page 3, section 3. dit " UTF-8 est défini par la norme Unicode ".

4voto

Andrew Points 4086

UTF-8 était un autre système pour stocker votre chaîne de points de code Unicode, ces chiffres U+ magiques, en mémoire en utilisant des octets de 8 bits. En UTF-8, chaque point de code de 0 à 127 est stocké dans un seul octet. Seuls les points de code 128 et supérieurs sont stockés en utilisant 2, 3, en fait, jusqu'à 6 octets.

Extrait de Le minimum absolu que tout développeur de logiciels doit absolument, positivement connaître sur Unicode et les jeux de caractères (pas d'excuses !)

0 votes

C'est un bon article, mais il semble que Joel se trompe concernant la longueur maximale de la séquence ; la page Wikipedia indique 1..4 octets par caractère, seulement.

4 votes

Comme je l'ai dit plus haut, lorsque l'UTF-8 a été créé, Unicode a revendiqué jusqu'à 32 bits pour les points de code, non pas parce qu'ils en avaient vraiment besoin, mais parce que 32 bits est une valeur pratique et qu'ils avaient déjà dépassé la limite précédente de 16 bits pour les caractères. Après que l'UTF-8 se soit avéré populaire, ils ont choisi de limiter pour toujours le nombre maximum de points de code à 2^21, qui est la plus grande valeur que vous pouvez coder avec 4 octets du schéma UTF-8. Il y a toujours moins de 2^17 caractères dans Unicode, donc nous pouvons plus que quadrupler le nombre de caractères dans Unicode avec ce nouveau schéma.

0 votes

Ok mais pas l'explication demandée par le PO.

2voto

Matthieu M. Points 101624

Je pense que le Article de Wikipedia répond à cette question. Ce qui est bien, c'est qu'il parle même de la combinaison des diacritiques et autres, ce que j'avais oublié il n'y a pas si longtemps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X