UNICODE

De knowledge
Révision datée du 14 janvier 2026 à 15:50 par Jpinon (discussion | contributions) (→‎UTF-8)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche

Généralités

1280px-Writing Systems.png

Il n'y a pas que l'anglais dans le monde!

Si si, même si notre français s'accommode sans trop de soucis à l'ASCII d'autres langues sont définitivement pas latines et ne savent pas. Le russe, l'arabe le chinois... (exemple ci-contre)

Cela nous fait pas mal de caractères à coder : Ա ࠂ ô ᚡ ... et y'en a d'autres!

On s'est mis d'accord pour créer le code UNICODE. https://www.compart.com/fr/unicode/

Chaque caractère à un numéro et on considère des blocs.

  • Pour les 127 premiers c'est le même numéro que l'ASCII. Tout va bien nos programmes en C resteront codés de la même façon!
  • Entre 128 et 255 on a des caractères dit ASCII étendu ou Latin 1. Ce sont les extensions à l'ASCII qui permettent d'écrire l'ensemble des langues européennes latines.

On a ensuite beaucoup de blocs pour des multitudes de systèmes d'écritures mais aussi pour des usages spécifiques, scientifique, linguistiques...

  • L'un des derniers est le bloc des idéogrammes CJK unifiés (à partir de caractère 196 608 et pour les 4 939 suivants (ca va de 𰀀 196608 à 𱍊 201546)

C'est ce qui a été normalisé par l'ISO et l'Europe dans la norme ISO/CEI 10646.

Codage

Ces caractères sont donc codés de zéro (le null ASCII) à 0x10 FFFF ou 1 114 111(un million cent quatorze mille cent douze caractères). En gros, et pour le moment, ca rentrerait sur 24 bits. On pourrait se dire qu'à partir de dorénavant on coderait tous les textes en 24 (32 c'est un multiple de 8) bits. Cependant, pour ceux qui ont la chance de pouvoir utiliser de l'ASCII ca fait clairement du ×4 en volume ce qui est dommage.

On a fait plusieurs systèmes que les différents utilisateurs peuvent choisir tant qu'ils se mettent d'accord au départ.

7 bits ASCII jusque là tout va bien on maitrise

Pour le reste ça se complique:

UTF32

C'est le plus simple mais celui qui prends le plus de place. Si on se mets d'accord sur ce codage au départ, tous les caractères seront une suite de 4 octets. Le chiffre zéro par exemple sera codé : 00 00 00 30 et le π (pi minuscule) sera noté 00 00 03 C0.

C'est brutal mais c'est très simple. On peut tout coder avec ça sans se poser de questions (sauf qu'il faut acheter de la RAM, du disque et de la bande passante en ×4)

Les encodages a taille variables.

Là on est plus subtil mais c'est plus compliqué a traiter. Chaque caractère peut être codé sur un nombre variables d'octets (UTF-8) ou de mots (UTF-16)

UTF-8 est massivement utilisé dans tous les domaines (web, machines Linux etc.) mais je crois que Windows s'acharne à utiliser UTF-16 (les processeur 16 bits des débuts y sont peut être pour quelque chose).

UTF-8

C'est le plus utilisé et le plus complexe à lire.

On lit les octets un par un. Pour chaque octet on regarde son bit de poids fort.

  • Si c'est un 0 alors les 7 bits suivants sont le caractère ASCII qui correspond. ON EST DONC COMPATIBLE ASCII !
  • Si le bit de poids fort est à 1 ca se complique... On compte alors les bits à 1 avant de tomber sur un 0. Ce nombre de bits à 1 corresponds à la longueur du caractère!
    • 110 (premier bit pour dire que c'est à taille variable et le second pour dire qu'il y en a encore un à lire) il nous reste alors 5 bits de "payload" sur ce caractère. Comme on a vu qu'il y avait un qui suivait, on le lit.
    • 1110 on devra lire deux octets ensuite et il reste 4 bits de payload.
    • 11110 on devra lire trois octets ensuite et il ne reste plus que deux bits de payload car le premier doit être à zéro je ne sais pas pourquoi.
    • 10 a un rôle spécial. C'est un octet de complément. Si on a un premier que commence par 110xxxxx il sera suivi d'un octet de valeur 19xxxxxx. Donc on peut coder sur deux octets des caractères de 11 bits (les 2048 premiers caractères UNICODE)

Cette subtilité des octets commençant par 10 permet à un process de lecture série (UART par exemple) de savoir "par où commencer". Lorsque on commence à lire on ignore tous les octets en 10xxxxxx car c'est la fin d'un caractère dont on a loupé le début. On commence à décoder dès qu'on a un octet ne commençant pas par 10.

Le résumé est donné dans ce tableau issue de Wikipédia.

Caractères codés Représentation binaire UTF-8 Premier octet valide (hexadécimal) Signification
U+0000 à U+007F 0ƀƀƀ·ƀƀƀƀ 00 à 7F 1 octet, codant jusqu’à 7 bits
U+0080 à U+07FF 110ƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ C2 à DF 2 octets, codant jusqu’à 11 bits
U+0800 à U+FFFF 1110·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ E0 à EF 3 octets, codant jusqu’à 16 bits
U+10000 à U+10FFFF 1111·00ƀƀ 10ƀƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ F0 à F3 4 octets, codant jusqu’à 21 bits

On note l'utilisation de ƀ caractère 180 en UNICODE, C6 80 en UTF-8 (Latin Small Letter B With Stroke)

On note qu'on perds plein de places dans le cas des caractères multi-bits.

Dans le cas de deux octets:

110ƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ

On pourrait imagine de coder un caractère de 7 bits:

110ƀ·ƀƀƀƀ 10ƀƀ·ƀƀƀƀ

Un 'A' (0x41) .000 0100 en binaire 7 bits donnerait:

1100·0000 1000·0100 soit 0xC0 0x84.Cela ferait que le 'A' pourrait avoir de multiple codage 0x41, 0xC0 0x84ou encode des codages sur 3 ou 4 octets mais c'est INTERDIT. Le seul codage de 'A' est 0x41.

Ceci explique la troisième colonne du tableau ci-dessus. Toutes les valeurs ne sont pas possibes.

UTF-16

Je trouve que c'est le plus moche. C'est un mix entre un codage en binaire brut de du codage en taille variable. C'est compliqué a décoder et incompatible avec ASCII.

Je n'y vois aucun intérêt pur le moment les infos sont sur Wikipedia. Je m'y plongerais si je re-programme sous Windows un jours.