85 votes

Combien de caractères peuvent être cartographiés avec Unicode ?

Je demande le compte de toutes les combinaisons valides possibles en Unicode avec explication. Je sais qu'un caractère peut être encodé en 1, 2, 3 ou 4 octets. Je ne comprends pas non plus pourquoi les octets de continuation ont des restrictions même si l'octet de départ de ce caractère indique sa longueur.

131voto

dan04 Points 33306

Je demande le compte de toutes les combinaisons valides possibles en Unicode avec explication.

1,111,998 : 17 plans × 65,536 caractères par plan - 2048 substituts - 66 non-caractères

Notez que UTF-8 et UTF-32 pourraient théoriquement encoder beaucoup plus que 17 plans, mais la plage est limitée en fonction des limitations de l'encodage UTF-16.

137,929 points de code sont réellement assignés dans Unicode 12.1.

Je ne comprends pas non plus pourquoi les octets de continuation ont des restrictions même si l'octet de démarrage de ce caractère indique sa longueur.

L'objectif de cette restriction en UTF-8 est de rendre l'encodage auto-synchronisant.

Par exemple, considérons l'encodage Chinois GB 18030. Là-bas, la lettre ß est représentée par la séquence d'octets 81 30 89 38, qui contient l'encodage des chiffres 0 et 8. Ainsi, si vous avez une fonction de recherche de chaîne non conçue pour cette particularité spécifique à cet encodage, une recherche du chiffre 8 trouvera un faux positif dans la lettre ß.

En UTF-8, cela ne peut pas se produire, car le non-chevauchement entre les octets de tête et les octets de queue garantit que l'encodage d'un caractère plus court ne peut jamais apparaître dans l'encodage d'un caractère plus long.

2 votes

L'article "auto-synchronisé" auquel vous avez fait référence n'explique pas du tout ce qui est auto-synchronisé

1 votes

Juste une note intéressante, UTF8 nécessite seulement 4 octets pour mapper tous les caractères Unicode, mais UTF8 peut prendre en charge jusqu'à 68 milliards de caractères si jamais nécessaire, utilisant jusqu'à 7 octets par caractère.

9voto

Simon Nickerson Points 17147

Unicode permet 17 plans, chacun comprenant 65 536 caractères possibles (ou 'points de code'). Cela donne un total de 1 114 112 caractères possibles. À l'heure actuelle, seul environ 10% de cet espace a été attribué.

Les détails précis de la manière dont ces points de code sont encodés diffèrent en fonction de l'encodage, mais votre question semble indiquer que vous pensez à l'UTF-8. La raison des restrictions sur les octets de continuation est probablement pour qu'il soit facile de trouver le début du prochain caractère (les caractères de continuation sont toujours de la forme 10xxxxxx, mais l'octet de départ ne peut jamais être de cette forme).

0 votes

Selon ces "plans", même les trois derniers octets d'un caractère de 4 octets pourraient en exprimer 64. Ai-je tort?

0 votes

Oui, il s'agit de synchronisation, voir cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt

2 votes

C'est dépassé je pense. Cela n'utilise plus 6 octets maintenant

5voto

Philipp Points 21479

Unicode prend en charge 1 114 112 points de code. Il existe 2048 points de code de substitution, donnant 1 112 064 valeurs scalaires. Parmi ceux-ci, il y a 66 caractères non valides, ce qui conduit à 1 111 998 caractères encodés possibles (sauf erreur de calcul de ma part).

0 votes

Pouvez-vous regarder ma réponse? Pourquoi y a-t-il 1 112 114 points de code?

3 votes

Ce nombre provient du nombre d'avions pouvant être adressés en utilisant le système de substitution UTF-16. Vous avez 1024 bas surrogates et 1024 haut surrogates, ce qui donne 1024² points de code non-BMP. Cela, ajouté aux 65 536 points de code BMP, donne exactement 1 114 112.

2 votes

@Philipp, mais tu donnes '1_112_114' dans ta réponse, alors que tu expliques '1_114_112' dans ton commentaire. Peut-être que tu as mélangé les 2 et 4.

1voto

nightcracker Points 34498

Selon Wikipedia, Unicode 12.1 (publié en mai 2019) contient 137 994 caractères distincts.

0 votes

@Ufuk: Unicode n'a pas de caractères. Il a des points de code. Parfois, plusieurs points de code sont nécessaires pour former un seul caractère. Par exemple, le caractère "5" est composé de deux points de code, tandis que le caractère "ñ" peut être composé d'un ou deux points de code (ou plus !). Il y a 2²¹ points de code possibles, mais certains d'entre eux sont réservés en tant que non-caractères ou caractères partiels.

6 votes

Unicode est une norme d'encodage de caractères. Première réponse de unicode.org/faq/basic_q.html : « Unicode est l'encodage de caractères universel », donc dire que « Unicode n'est pas un encodage » est incorrect. (J'ai moi-même fait cette erreur autrefois.)

1 votes

@tchrist : La norme Unicode définit plusieurs termes, parmi lesquels "caractère abstrait" et "caractère encodé". Donc dire que Unicode n'a pas de caractères n'est pas non plus vrai.

1voto

Andy Finkenstadt Points 2765

Pour donner une réponse métaphoriquement précise, tous.

Les octets de continuation dans les encodages UTF-8 permettent la resynchronisation du flux d'octets encodés face au "bruit de ligne". L'encodeur n'a simplement besoin de scanner vers l'avant pour un octet qui n'a pas de valeur entre 0x80 et 0xBF pour savoir que le prochain octet est le début d'un nouveau point de caractère.

En théorie, les encodages utilisés aujourd'hui permettent l'expression de caractères dont le nombre de caractères Unicode est jusqu'à 31 bits de longueur. En pratique, cet encodage est réellement implémenté sur des services comme Twitter, où le tweet de longueur maximale peut encoder jusqu'à 4 340 bits de données (140 caractères [valides et invalides], multipliés par 31 bits chacun).

0 votes

En réalité, en théorie, ce n'est pas limité à 31 bits, vous pouvez aller plus grand sur une machine 64 bits. perl -le 'print ord "\x{1FFF_FFFF_FFFF}"' imprime 35184372088831 sur une machine 64 bits, mais provoque un débordement d'entier sur une machine 32 bits. Vous pouvez utiliser des caractères plus grands comme ça à l'intérieur de votre programme perl, mais si vous essayez de les afficher en utf8, vous obtenez un avertissement obligatoire sauf si vous désactivez cela: perl -le 'print "\x{1FFF_FFFF}"' Point de code 0x1FFFFFFF n'est pas Unicode, peut ne pas être portable à la ligne -e 1. ######. Il y a une différence entre "utf8 lâche" et "UTF-8 strict" : le premier n'est pas restreint.

1 votes

Les encodages utilisés aujourd'hui ne permettent pas des valeurs scalaires de 31 bits. UTF-32 permettrait des valeurs de 32 bits, UTF-8 pour encore plus, mais UTF-16 (utilisé en interne par Windows, OS X, Java, .NET, Python, et donc le schéma d'encodage le plus populaire) permet juste plus d'un million (ce qui devrait tout de même suffire).

0 votes

@Philip : Tu as tort sur certains points. Python utilise UCS-2 ou, avec une construction large, UCS-4 ; il n'utilise pas UTF-16. Le noyau BSD d'OS X utilise l'API Unix normale, ce qui lui permet d'utiliser UTF-8 pour HSF+ et non UTF-16. Et je viens de démontrer que Perl permet beaucoup plus que ce que tu as dit.

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