Selon l'article de Wikipedia , UTF-8 a ce format:
Premier code Dernier code Octets Octet 1 Octet 2 Octet 3 Octet 4 point point Utilisé U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 07FF 2 110xxxxx 10xxxxxx U + 0800 U + FFFF 3 1110xxxx 10xxxxxx 10xxxxxx U + 10000 U + 1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx x signifie que ce bit est utilisé pour sélectionner le point de code.
Cela gaspille deux bits sur chaque octet de continuation et un bit dans le premier octet. Pourquoi UTF-8 n'est-il pas encodé comme suit?
Premier code Dernier code Octets Octet 1 Octet 2 Octet 3 point point Utilisé U + 0000 U + 007F 1 0xxxxxxx U + 0080 U + 3FFF 2 10xxxxxx xxxxxxxx U + 0800 U + 1FFFFF 3 110xxxxx xxxxxxxx xxxxxxxx
Il enregistrerait un octet lorsque le point de code est hors du plan multilingue de base ou si le point de code est dans la plage [U + 800, U + 3FFF].
Pourquoi UTF-8 n'est-il pas encodé de manière plus efficace?
Réponses:
Ceci est fait pour que vous puissiez détecter quand vous êtes au milieu d'une séquence multi-octets. Lorsque vous regardez les données UTF-8, vous savez que si vous voyez
10xxxxxx
, que vous êtes au milieu d'un caractère multi-octets, et que vous devez sauvegarder dans le flux jusqu'à ce que vous voyiez soit0xxxxxx
ou11xxxxxx
. En utilisant votre schéma, les octets 2 ou 3 pourraient facilement se retrouver avec des motifs tels que0xxxxxxx
ou11xxxxxx
Gardez également à l'esprit que la quantité enregistrée varie entièrement en fonction du type de données de chaîne que vous encodez. Pour la plupart des textes, même les textes asiatiques, vous verrez rarement, voire jamais, des caractères de quatre octets avec du texte normal. De plus, les estimations naïves des gens sur l'apparence du texte sont souvent fausses. J'ai un texte localisé pour UTF-8 qui comprend des chaînes japonaises, chinoises et coréennes, mais c'est en fait le russe qui prend le plus de place. (Parce que nos chaînes asiatiques ont souvent des caractères romains intercalés pour les noms propres, la ponctuation et autres et parce que le mot chinois moyen est de 1 à 3 caractères tandis que le mot russe moyen est beaucoup, beaucoup plus.)
la source
La manière officielle permet au décodeur de savoir quand il est au milieu du tuple et il sait ignorer les octets (ou revenir en arrière) jusqu'à ce que l'octet commence par
0
ou11
; cela empêche les valeurs inutiles lorsqu'un seul octet est corrompu.la source
Réponse courte, votre proposition ne fait pas de distinction entre le premier octet et les octets de continuation.
Le modèle de bits à l'extrémité supérieure du premier octet vous indique avec combien d'octets le caractère réel est construit. Ces modèles fournissent également une reconnaissance des erreurs lors de l'analyse d'une chaîne. Si vous lisez (apparemment) le premier octet d'un caractère et que vous obtenez 10xxxxxx, vous savez que vous n'êtes pas synchronisé.
la source
Ce qui n'a pas été mentionné, c'est que si vous avez une séquence correcte de points de code et un pointeur qui est garanti pour pointer vers le premier octet d'un point de code, avec UTF-8, vous pouvez très facilement trouver le pointeur vers le premier octet du point de code précédent (ignorer tous les octets commençant par 01xx xxxx). Avec votre encodage, c'est impossible sans potentiellement examiner tous les octets jusqu'au début de la chaîne.
Considérons les séquences de (2n + 2) octets
et
Si vous avez un pointeur sur le premier octet du premier point de code après cette séquence, vous devez examiner tous les octets pour savoir si le dernier point de code est 0xxxxxxx ou (10xxxxxx, 0xxxxxxx).
Il existe en fait des schémas de codage plus efficaces, où le passage au point de code précédent peut se faire en temps constant, et les pointeurs vers le milieu d'un point de code peuvent être fixés. Autorisez les codes suivants:
Si l'un des trois octets précédents est ≥ 236, c'est le début d'une séquence de 3 octets, car il ne peut y avoir deux de ces octets dans une séquence de 3 octets valide. Sinon, si l'un des deux octets précédents est ≥ 128, c'est le début d'une séquence de deux octets. Sinon, l'octet précédent est un seul octet <128.
La recherche d'une sous-chaîne devient légèrement plus difficile. Vous souhaiterez peut-être exclure zéro octet afin qu'une chaîne ne contienne un octet nul que si elle contient un point de code zéro.
la source