Encodage UTF-16
UTF-16 (format de transformation Unicode de 16 bits) est l'encodage de caractères à largeur variable qui représente les valeurs scalaires Unicode à l'aide d'une ou deux unités de code de 16 bits (2 ou 4 octets). Les caractères du plan multilingue de base (U+0000 à U+D7FF et U+E000 à U+FFFF) sont mappés directement sur une seule unité de 16 bits. Les caractères des plans supplémentaires (U+10000 à U+10FFFF) — dont les émojis, les alphanumériques mathématiques et les écritures historiques — sont encodés à l'aide d'une paire ordonnée d'unités de code réservées appelée paire de substitution.
Données techniques rapides
U+0000–U+D7FF & U+E000–U+FFFF
Mappage scalaire direct 1:1 (1 unité, 2 octets)
U+D800–U+DFFF
2,048 unités réservées ; pas des caractères scalaires
U+10000–U+10FFFF
Encodés en paires de substitution (2 unités, 4 octets)
U+FEFF)
BE: FE FF | LE: FF FE
Espace de code et distribution des plages UTF-16
Le standard Unicode partitionne tout l'espace de $1,114,112$ points de code en plans. UTF-16 gère les points de code avec des unités de 16 bits simples pour les caractères scalaires du BMP et des paires d'unités de 16 bits pour les caractères supplémentaires, conformément au tableau 3-5 du standard Unicode 18.0.
| Plan de caractères | Plage scalaire | Unités de code | Longueur en octets | Plage d'unités de code (hex) | Statut d'encodage |
|---|---|---|---|---|---|
|
Basic Multilingual Plane (BMP, Lower)
Covers ASCII, Latin, Greek, Cyrillic, Hebrew, Arabic, and most common scripts.
|
U+0000–U+D7FF |
1 Unité | 2 Octets |
0000–D7FF |
Single Code Unit (Direct 1:1 scalar mapping) |
|
High-Surrogate Range (Lead Surrogates)
Permanently reserved for the leading unit of a surrogate pair. Cannot stand alone.
|
U+D800–U+DBFF |
1 Unité | 2 Octets |
D800–DBFF |
Reserved High Surrogates (Not Scalar Values) |
|
Low-Surrogate Range (Trail Surrogates)
Permanently reserved for the trailing unit of a surrogate pair. Cannot stand alone.
|
U+DC00–U+DFFF |
1 Unité | 2 Octets |
DC00–DFFF |
Reserved Low Surrogates (Not Scalar Values) |
|
Basic Multilingual Plane (BMP, Upper)
Private Use Area, CJK compatibility, alphabetic presentation forms, specials.
|
U+E000–U+FFFF |
1 Unité | 2 Octets |
E000–FFFF |
Single Code Unit (Direct 1:1 scalar mapping) |
|
Supplementary Planes (Planes 1–16)
Contains emojis, historic scripts (Linear B, Egyptian Hieroglyphs), musical notation, rare CJK ideographs.
|
U+10000–U+10FFFF |
2 Unités | 4 Octets |
D800 DC00 – DBFF DFFF |
Surrogate Pair Required (High Surrogate + Low Surrogate) |
Le mécanisme de la paire de substitution
Comme une seule unité de code de 16 bits peut adresser au plus $65,536$ valeurs, Unicode a réservé $2,048$ unités de code dans le plan multilingue de base (plan 0) spécifiquement pour encoder les $1,048,576$ caractères supplémentaires (plans 1–16).
0xD800–0xDBFF0xDC00–0xDFFF1. Formule d'encodage (scalaire vers substituts)
Pour tout point de code supplémentaire $C$ où $0\text{x}10000 \le C \le 0\text{x}10\text{FFFF}$ :
U' = C - 0x10000;HighSurrogate = 0xD800 + (U' >> 10);LowSurrogate = 0xDC00 + (U' & 0x3FF);
Soustraire $0\text{x}10000$ produit un nombre de 20 bits ($2^{20} = 1,048,576$). Le découpage en deux moitiés de 10 bits s'insère parfaitement dans les deux fenêtres de substitution de 1,024 unités.
2. Formule de décodage (substituts vers scalaire)
Étant donnés un substitut haut valide $W_1$ et un substitut bas valide $W_2$ :
C = 0x10000 + ((W1 - 0xD800) << 10) + (W2 - 0xDC00);
Inverse les décalages de 10 bits et ajoute le décalage $0\text{x}10000$ pour reconstruire la valeur scalaire Unicode exacte de 21 bits.
Inspecteur et validateur UTF-16 interactif
Explorez en direct l'encodage des unités de code UTF-16, basculez entre les sérialisations d'octets Big-Endian et Little-Endian, ou saisissez des unités de code hexadécimales brutes pour valider la conformité des séquences.
D83D DE00
D8 3D DE 00
3D D8 00 DE
0xD83D suivi du substitut bas 0xDE00, décodant ensemble en U+1F600. Exemple résolu : encodage de 😀 (U+1F600)
Suivez la dérivation mathématique et de décalage de bits exacte définie par le standard Unicode 18.0 pour convertir la valeur scalaire supplémentaire U+1F600 en sa paire de substitution UTF-16 D83D DE00.
0x1F600 - 0x10000 = 0x0F600
High 10 bits: 0x03D (0000111101) | Low 10 bits: 0x200 (1000000000)
0xD800 + 0x03D = 0xD83D
0xDC00 + 0x200 = 0xDE00
D83D DE00
Vérification par décodage inverse
C = 0x10000 + ((0xD83D - 0xD800) << 10) + (0xDE00 - 0xDC00)
C = 0x10000 + (0x03D × 1024) + 0x200 = 0x10000 + 0xF400 + 0x200 = 0x1F600 (U+1F600) ✓
La formule inverse reconstruit la valeur scalaire d'origine avec une fidélité mathématique de 100 %.
Exemples représentatifs à travers les plans
Caractères Unicode représentatifs, symboles mathématiques, écritures historiques, signes combinants et séquences d'émojis complexes encodés en UTF-16.
Latin Capital Letter A
ASCII / Basic Latin0041
00 41
41 00
1 code unit (2 bytes). Illustrates 16-bit BMP encoding where high byte is 0x00.
Latin Small Letter E with Acute
Latin-1 Supplement00E9
00 E9
E9 00
1 code unit (2 bytes). Precomposed BMP accented character.
Euro Sign
Currency Symbols20AC
20 AC
AC 20
1 code unit (2 bytes). Common BMP business character (0x20AC).
Infinity
Mathematical Operators221E
22 1E
1E 22
1 code unit (2 bytes). BMP mathematical symbol (0x221E).
Grinning Face
Emoji / SMPD83D DE00
D8 3D DE 00
3D D8 00 DE
2 code units (4 bytes). Canonical emoji surrogate pair: D83D DE00.
Linear B Ideogram B105F Mare
Historic Scripts (SMP)D800 DC83
D8 00 DC 83
00 D8 83 DC
2 code units (4 bytes). Tests high surrogate lower boundary (0xD800).
CJK Unified Ideographs Extension B
Rare CJK Ideograph (SIP)D869 DEA5
D8 69 DE A5
69 D8 A5 DE
2 code units (4 bytes). Plane 2 Ideograph: U+2A6A5 -> D869 DEA5.
Combining E + Acute Accent
Combining Sequence0065 0301
00 65 03 01
65 00 01 03
2 code points, 2 code units (4 bytes). 1 perceived glyph = 2 code units.
Woman Technologist
ZWJ Emoji SequenceD83D DC69 200D D83D DCBB
D8 3D DC 69 20 0D D8 3D DC BB
3D D8 69 DC 0D 20 3D D8 BB DC
3 code points, 5 UTF-16 code units (10 bytes). Complex sequence joined by ZWJ.
Ordre des octets et sérialisation : UTF-16BE contre UTF-16LE
UTF-16 définit une forme d'encodage utilisant des unités de code de 16 bits. Quand ces entiers de 16 bits sont sérialisés en un flux d'octets de 8 bits (pour la transmission réseau ou le stockage), l'ordre des deux octets au sein de chaque unité de code est régi par le schéma d'encodage : Big-Endian ou Little-Endian.
| Caractère | Point de code | Unités de code de 16 bits | UTF-16BE (Big-Endian) | UTF-16LE (Little-Endian) | Comportement de sérialisation |
|---|---|---|---|---|---|
| A | U+0041 |
0041 |
00 41 |
41 00 |
ASCII: Big-Endian places 00 first; Little-Endian places 41 first. |
| € | U+20AC |
20AC |
20 AC |
AC 20 |
Euro Sign: Single code unit 20AC inverted in Little-Endian. |
| ∞ | U+221E |
221E |
22 1E |
1E 22 |
Infinity: Single code unit 221E inverted in Little-Endian. |
| 😀 | U+1F600 |
D83D DE00 |
D8 3D DE 00 |
3D D8 00 DE |
Emoji: Note that each 16-bit code unit is byte-swapped individually! |
| 𐂃 | U+10083 |
D800 DC83 |
D8 00 DC 83 |
00 D8 83 DC |
Historic script: D800 DC83 serialized to 00 D8 83 DC in Little-Endian. |
Note importante sur l'échange des substituts
En sérialisant une paire de substitution en mode Little-Endian (UTF-16LE), chaque unité de code de 16 bits est échangée par octets individuellement. L'ordre des deux unités de code reste inchangé : le substitut haut précède toujours le substitut bas. Par exemple, D83D DE00 devient 3D D8 00 DE, et NON 00 DE 3D D8.
Sémantique de la marque d'ordre des octets (BOM)
La marque d'ordre des octets (BOM) est le caractère Unicode U+FEFF (ESPACE SANS CHASSE INSÉCABLE). Placée au début d'un flux UTF-16 sérialisé, son motif d'octets révèle immédiatement si le flux est Big-Endian ou Little-Endian.
L'octet de poids fort 0xFE précède l'octet de poids faible 0xFF. Signale un ordre des octets Big-Endian.
L'octet de poids faible 0xFF précède l'octet de poids fort 0xFE. Signale un ordre des octets Little-Endian.
| Contexte du flux | Statut d'exigence | Explication normative |
|---|---|---|
| Explicitly Labeled Streams (e.g. charset=utf-16le or utf-16be) | Optional / Not Required | When the MIME type or transport layer explicitly declares the endianness, the byte order is already known. |
| Generic "UTF-16" Byte Streams (without BE/LE designation) | Recommended for Detection | If labeled simply "UTF-16", an initial BOM identifies whether the stream is Big-Endian (FE FF) or Little-Endian (FF FE). |
| Generic "UTF-16" Streams Lacking a BOM | Default to Big-Endian | Per RFC 2781 Section 4.3, in the absence of a BOM, systems without prior agreement should interpret generic UTF-16 as Big-Endian (UTF-16BE). |
| Mid-Stream Occurrence of U+FEFF | Treated as Zero-Width No-Break Space | If U+FEFF appears after the stream header, it is treated as a non-breaking space character, though U+2060 (Word Joiner) is preferred. |
Le mythe de l'exigence universelle
UTF-16 n'exige PAS universellement une BOM. Bien que courante dans les fichiers texte Windows (comme les fichiers .txt du Bloc-notes étiquetés "Unicode"), les protocoles spécifiant charset=utf-16le ou charset=utf-16be n'en exigent explicitement pas. Dans les applications web, le standard d'encodage du WHATWG se base sur UTF-8, mais décode les flux UTF-16 étiquetés selon la BOM explicite ou les définitions MIME.
Bonne formation et séquences de substitution mal formées
Une séquence d'unités de code UTF-16 est bien formée si et seulement si chaque unité substitut apparaît dans une séquence correctement appariée et ordonnée. Tout substitut isolé ou dépareillé viole le standard Unicode 18.0 §3.9 (définition D92).
Invariants de conformité Unicode
- Règle 1 (scalaires du BMP) : les unités de code de 16 bits simples doivent tomber dans
U+0000..U+D7FFouU+E000..U+FFFF. - Règle 2 (substituts hauts) : tout substitut haut (
0xD800..0xDBFF) doit être immédiatement suivi d'un substitut bas (0xDC00..0xDFFF). - Règle 3 (substituts bas) : tout substitut bas (
0xDC00..0xDFFF) doit être immédiatement précédé d'un substitut haut (0xD800..0xDBFF). - Règle 4 (non-caractères) : les non-caractères (comme
U+FDD0..U+FDEF,U+FFFE,U+FFFF) sont des valeurs scalaires Unicode valides et ne doivent jamais être traités comme des erreurs de substitution.
| Unités de code (hex) | Classification de l'erreur | Décalage de l'erreur | Diagnostic de conformité au standard | Risque de sécurité et d'analyse |
|---|---|---|---|---|
D800 |
UNPAIRED_HIGH_SURROGATE | Position 0 |
Isolated High Surrogate at end of sequence with no matching low surrogate. | String truncation vulnerability; decoders may discard or generate replacement characters (U+FFFD). |
D83D 0041 |
EXPECTED_LOW_SURROGATE | Position 1 |
High surrogate (D83D) followed by ASCII letter A (0041) instead of a low surrogate (DC00..DFFF). | Surrogate desynchronization; downstream parsers may misinterpret payload boundaries. |
DC00 |
UNPAIRED_LOW_SURROGATE | Position 0 |
Isolated Low Surrogate encountered without a preceding high surrogate. | Orphaned trailing surrogate; causes malformed string crashes in strict environments. |
DC00 D83D |
UNPAIRED_LOW_SURROGATE | Position 0 |
Inverted surrogate order: low surrogate (DC00) appears before high surrogate (D83D). | Surrogate inversion produces two ill-formed code units; rejected by standard decoders. |
D800 D800 |
EXPECTED_LOW_SURROGATE | Position 1 |
Two consecutive high surrogates; the first high surrogate is never completed. | Surrogate stacking error; common when slice operations cut strings through surrogate boundaries. |
0041 D83D |
TRUNCATED_SURROGATE_PAIR | Position 1 |
Valid ASCII A (0041) followed by high surrogate D83D truncated before its low surrogate. | Buffer cutoff at surrogate boundary. |
Concepts fondamentaux et architecture
Distinctions essentielles pour implémenter et déboguer correctement les chaînes UTF-16 dans les logiciels modernes.
Code Unit vs. Code Point vs. Byte
In UTF-16, a code unit is 16 bits (2 bytes). A code point is a numeric index in the Unicode codespace. In the BMP, 1 code point = 1 code unit = 2 bytes. In supplementary planes (e.g. 😀), 1 code point = 2 code units = 4 bytes.
User-Perceived Characters & Grapheme Clusters
A single visible character on screen can require more than one code point. For example, 👩💻 (Woman Technologist) consists of 3 code points (Woman U+1F469, ZWJ U+200D, Laptop U+1F4BB) and spans 5 UTF-16 code units (10 serialized bytes). Do not confuse code unit counts with human-perceived characters.
UTF-16 vs. UCS-2
UCS-2 was a legacy fixed-width 16-bit encoding that only supported the Basic Multilingual Plane (U+0000..U+FFFF). UCS-2 had no concept of surrogate pairs and could not represent characters beyond 0xFFFF. UTF-16 superseded UCS-2 by introducing surrogate pairs, enabling representation of all 1,114,112 Unicode code points.
UTF-16 vs. UTF-8
UTF-8 is an 8-bit byte-oriented variable-width encoding (1 to 4 bytes per scalar) that is strictly ASCII-compatible. UTF-16 is a 16-bit code-unit variable-width encoding (2 or 4 bytes per scalar). UTF-8 dominates the web, while UTF-16 is widely used as an in-memory string representation in operating systems and runtimes.
Programming String Length Pitfall (JS, Java, C#)
Many programming language string implementations (such as JavaScript "string".length, Java String.length(), and C# string.Length) count 16-bit UTF-16 code units rather than Unicode code points. Consequently, "😀".length reports 2 instead of 1. Use Array.from(str).length or code-point-aware iterators to count true characters.
Encodages de caractères connexes
Normes de référence et références normatives
Toutes les données, calculs de substitution, règles de bonne formation et ordres de sérialisation des octets de cette page dérivent directement de normes techniques normatives :
- The Unicode Standard, Version 17.0 — Section 3.8 (Surrogates) & Section 3.9 (Unicode Encoding Forms - Table 3-5) (Unicode Consortium)
- RFC 2781 — UTF-16, an encoding of ISO 10646 (Internet Engineering Task Force (IETF))
- WHATWG Encoding Standard — Section 4.5 (utf-16be) & Section 4.6 (utf-16le) (Web Hypertext Application Technology Working Group (WHATWG))