Vai al contenuto principale
Codifica a 16 bit a larghezza variabile Unicode Standard 17.0 §3.8 & §3.9 RFC 2781

Codifica UTF-16

UTF-16 (formato di trasformazione Unicode a 16 bit) è la codifica di caratteri a larghezza variabile che rappresenta i valori scalari Unicode mediante una o due unità di codice a 16 bit (2 o 4 byte). I caratteri del piano multilingue di base (U+0000 a U+D7FF e U+E000 a U+FFFF) sono mappati direttamente su una singola unità a 16 bit. I caratteri dei piani supplementari (U+10000 a U+10FFFF) — tra cui emoji, alfanumerici matematici e scritture storiche — sono codificati mediante una coppia ordinata di unità di codice riservate chiamata coppia surrogata.

Dati tecnici rapidi

Dimensione unità di codice 16-bit Code Units (2 Bytes) Unità fondamentale della forma di codifica
Unità per valore scalare 1 or 2 Code Units (2 or 4 Bytes) 1 unità per il BMP; 2 unità per i supplementari
Piano multilingue di base (BMP) U+0000–U+D7FF & U+E000–U+FFFF Mappatura scalare diretta 1:1 (1 unità, 2 byte)
Surrogati riservati U+D800–U+DFFF 2,048 unità riservate; non sono caratteri scalari
Piani supplementari (1–16) U+10000–U+10FFFF Codificati come coppie surrogate (2 unità, 4 byte)
Ordine dei byte UTF-16BE / UTF-16LE Serializzazione Big-Endian o Little-Endian
Marca d'ordine dei byte (BOM) Opzionale (U+FEFF) BE: FE FF | LE: FF FE
Baseline di standard Unicode 18.0 §3.8, §3.9 Table 3-5 / RFC 2781 Standard del Unicode Consortium & dell'IETF

Spazio di codice e distribuzione degli intervalli UTF-16

Lo standard Unicode partiziona l'intero spazio di $1,114,112$ punti di codice in piani. UTF-16 gestisce i punti di codice con singole unità a 16 bit per i caratteri scalari del BMP e coppie di unità a 16 bit per i caratteri supplementari, in conformità con la tabella 3-5 dello standard Unicode 18.0.

Piano di caratteri Intervallo scalare Unità di codice Lunghezza in byte Intervallo unità di codice (hex) Stato di codifica
Basic Multilingual Plane (BMP, Lower)
Covers ASCII, Latin, Greek, Cyrillic, Hebrew, Arabic, and most common scripts.
U+0000–U+D7FF 1 Unità 2 Byte 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 Byte 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 Byte 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 Byte 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à 4 Byte D800 DC00 – DBFF DFFF Surrogate Pair Required (High Surrogate + Low Surrogate)

Il meccanismo della coppia surrogata

Poiché una singola unità di codice a 16 bit può indirizzare al massimo $65,536$ valori, Unicode ha riservato $2,048$ unità di codice nel piano multilingue di base (piano 0) specificamente per codificare gli $1,048,576$ caratteri supplementari (piani 1–16).

Anatomia di una coppia surrogata (esempio: 😀 U+1F600) 2 unità di codice = 4 byte = 1 carattere Unicode
Surrogato alto (iniziale)
D83D
Intervallo: 0xD800–0xDBFF
Codifica i 10 bit alti ($0\text{x}03\text{D}$)
+
Surrogato basso (finale)
DE00
Intervallo: 0xDC00–0xDFFF
Codifica i 10 bit bassi ($0\text{x}200$)
=
Carattere Unicode decodificato
😀
U+1F600
Grinning Face (1 valore scalare)

1. Formula di codifica (scalare verso surrogati)

Per qualsiasi punto di codice supplementare $C$ dove $0\text{x}10000 \le C \le 0\text{x}10\text{FFFF}$:

U' = C - 0x10000;
HighSurrogate = 0xD800 + (U' >> 10);
LowSurrogate = 0xDC00 + (U' & 0x3FF);

Sottrarre $0\text{x}10000$ produce un numero a 20 bit ($2^{20} = 1,048,576$). La suddivisione in due metà da 10 bit si inserisce perfettamente nelle due finestre surrogate da 1,024 unità.

2. Formula di decodifica (surrogati verso scalare)

Dati un surrogato alto valido $W_1$ e un surrogato basso valido $W_2$:

C = 0x10000 + ((W1 - 0xD800) << 10) + (W2 - 0xDC00);

Inverte gli shift di 10 bit e aggiunge l'offset $0\text{x}10000$ per ricostruire l'esatto valore scalare Unicode a 21 bit.

Ispettore e validatore UTF-16 interattivo

Esplora in tempo reale la codifica delle unità di codice UTF-16, alterna le serializzazioni di byte Big-Endian e Little-Endian, o inserisci unità di codice esadecimali grezze per validarne la conformità delle sequenze.

Preimpostazioni rapide:
Formato di visualizzazione:
Punti di codice: 1
Unità di codice UTF-16: 2
Byte serializzati: 4
Cluster di grafemi: 1
Unità di codice UTF-16 esadecimali:
D83D DE00
😀 U+1F600
Piano multilingue supplementare Coppia surrogata richiesta
Surrogato alto: D83D
Surrogato basso: DE00
Byte BE: D8 3D DE 00
Byte LE: 3D D8 00 DE

Esempio svolto: codifica di 😀 (U+1F600)

Segui l'esatta derivazione matematica e di shifting di bit definita dallo standard Unicode 18.0 per convertire il valore scalare supplementare U+1F600 nella sua coppia surrogata UTF-16 D83D DE00.

Passaggio 1
Subtract 0x10000
0x1F600 - 0x10000 = 0x0F600
Subtracting the base 0x10000 reduces the code point to a 20-bit value (0x00000..0xFFFFF).
Passaggio 2
Extract High & Low 10 Bits
High 10 bits: 0x03D (0000111101) | Low 10 bits: 0x200 (1000000000)
Split the 20-bit offset into two 10-bit values (0 to 1023 each).
Passaggio 3
Add High Surrogate Base (0xD800)
0xD800 + 0x03D = 0xD83D
The high (leading) surrogate unit is computed by adding the top 10 bits to 0xD800.
Passaggio 4
Add Low Surrogate Base (0xDC00)
0xDC00 + 0x200 = 0xDE00
The low (trailing) surrogate unit is computed by adding the lower 10 bits to 0xDC00.
Passaggio 5
Surrogate Pair Result
D83D DE00
Together, the ordered pair <0xD83D, 0xDE00> represents U+1F600 in UTF-16.

Verifica mediante decodifica inversa

C = 0x10000 + ((0xD83D - 0xD800) << 10) + (0xDE00 - 0xDC00)
C = 0x10000 + (0x03D × 1024) + 0x200 = 0x10000 + 0xF400 + 0x200 = 0x1F600 (U+1F600) ✓

La formula inversa ricostruisce il valore scalare originale con una fedeltà matematica del 100%.

Esempi rappresentativi tra i piani

Caratteri Unicode rappresentativi, simboli matematici, scritture storiche, segni combinanti e sequenze emoji complesse codificati in UTF-16.

A

Latin Capital Letter A

ASCII / Basic Latin
Unità di codice UTF-16: 0041
Byte serializzati BE: 00 41
Byte serializzati LE: 41 00
1 Codice Unità 2 Byte 1 Punto di codice

1 code unit (2 bytes). Illustrates 16-bit BMP encoding where high byte is 0x00.

é

Latin Small Letter E with Acute

Latin-1 Supplement
Unità di codice UTF-16: 00E9
Byte serializzati BE: 00 E9
Byte serializzati LE: E9 00
1 Codice Unità 2 Byte 1 Punto di codice

1 code unit (2 bytes). Precomposed BMP accented character.

€

Euro Sign

Currency Symbols
Unità di codice UTF-16: 20AC
Byte serializzati BE: 20 AC
Byte serializzati LE: AC 20
1 Codice Unità 2 Byte 1 Punto di codice

1 code unit (2 bytes). Common BMP business character (0x20AC).

∞

Infinity

Mathematical Operators
Unità di codice UTF-16: 221E
Byte serializzati BE: 22 1E
Byte serializzati LE: 1E 22
1 Codice Unità 2 Byte 1 Punto di codice

1 code unit (2 bytes). BMP mathematical symbol (0x221E).

😀

Grinning Face

Emoji / SMP
Unità di codice UTF-16: D83D DE00
Byte serializzati BE: D8 3D DE 00
Byte serializzati LE: 3D D8 00 DE
2 Codice Unità 4 Byte 1 Punto di codice

2 code units (4 bytes). Canonical emoji surrogate pair: D83D DE00.

𐂃

Linear B Ideogram B105F Mare

Historic Scripts (SMP)
Unità di codice UTF-16: D800 DC83
Byte serializzati BE: D8 00 DC 83
Byte serializzati LE: 00 D8 83 DC
2 Codice Unità 4 Byte 1 Punto di codice

2 code units (4 bytes). Tests high surrogate lower boundary (0xD800).

𪚥

CJK Unified Ideographs Extension B

Rare CJK Ideograph (SIP)
Unità di codice UTF-16: D869 DEA5
Byte serializzati BE: D8 69 DE A5
Byte serializzati LE: 69 D8 A5 DE
2 Codice Unità 4 Byte 1 Punto di codice

2 code units (4 bytes). Plane 2 Ideograph: U+2A6A5 -> D869 DEA5.

é

Combining E + Acute Accent

Combining Sequence
Unità di codice UTF-16: 0065 0301
Byte serializzati BE: 00 65 03 01
Byte serializzati LE: 65 00 01 03
2 Codice Unità 4 Byte 2 Punti di codice

2 code points, 2 code units (4 bytes). 1 perceived glyph = 2 code units.

👩‍💻

Woman Technologist

ZWJ Emoji Sequence
Unità di codice UTF-16: D83D DC69 200D D83D DCBB
Byte serializzati BE: D8 3D DC 69 20 0D D8 3D DC BB
Byte serializzati LE: 3D D8 69 DC 0D 20 3D D8 BB DC
5 Codice Unità 10 Byte 3 Punti di codice

3 code points, 5 UTF-16 code units (10 bytes). Complex sequence joined by ZWJ.

Ordine dei byte e serializzazione: UTF-16BE vs UTF-16LE

UTF-16 definisce una forma di codifica che usa unità di codice a 16 bit. Quando questi interi a 16 bit vengono serializzati in un flusso di byte a 8 bit (per trasmissione in rete o archiviazione), l'ordine dei due byte all'interno di ogni unità di codice è governato dallo schema di codifica: Big-Endian o Little-Endian.

Carattere Punto di codice Unità di codice a 16 bit UTF-16BE (Big-Endian) UTF-16LE (Little-Endian) Comportamento di serializzazione
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.

Nota importante sullo scambio dei surrogati

Serializzando una coppia surrogata in modalità Little-Endian (UTF-16LE), ogni unità di codice a 16 bit viene scambiata byte per byte individualmente. L'ordine delle due unità di codice rimane invariato: il surrogato alto precede sempre il surrogato basso. Ad esempio, D83D DE00 diventa 3D D8 00 DE, NON 00 DE 3D D8.

Semantica della marca d'ordine dei byte (BOM)

La marca d'ordine dei byte (BOM) è il carattere Unicode U+FEFF (SPAZIO UNIFICATORE SENZA INTERRUZIONE). Posta all'inizio di un flusso UTF-16 serializzato, il suo schema di byte rivela immediatamente se il flusso è Big-Endian o Little-Endian.

Firma UTF-16BE
FE FF

Il byte di ordine superiore 0xFE precede il byte di ordine inferiore 0xFF. Segnala un ordine dei byte Big-Endian.

Firma UTF-16LE
FF FE

Il byte di ordine inferiore 0xFF precede il byte di ordine superiore 0xFE. Segnala un ordine dei byte Little-Endian.

Contesto del flusso Stato del requisito Spiegazione normativa
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.

Il mito del requisito universale

UTF-16 NON richiede universalmente una BOM. Sebbene sia comune nei file di testo Windows (come i file .txt del Blocco note etichettati "Unicode"), i protocolli che specificano charset=utf-16le o charset=utf-16be non la richiedono esplicitamente. Nelle applicazioni web, lo standard di codifica del WHATWG si basa su UTF-8, ma decodifica i flussi UTF-16 etichettati secondo la BOM esplicita o le definizioni MIME.

Buona formazione e sequenze surrogate malformate

Una sequenza di unità di codice UTF-16 è ben formata se e solo se ogni unità surrogata compare come parte di una sequenza correttamente appaiata e ordinata. Qualsiasi surrogato isolato o disallineato viola lo standard Unicode 18.0 §3.9 (definizione D92).

Invarianti di conformità Unicode

  • Regola 1 (scalari del BMP): le singole unità di codice a 16 bit devono ricadere in U+0000..U+D7FF o U+E000..U+FFFF.
  • Regola 2 (surrogati alti): qualsiasi surrogato alto (0xD800..0xDBFF) deve essere immediatamente seguito da un surrogato basso (0xDC00..0xDFFF).
  • Regola 3 (surrogati bassi): qualsiasi surrogato basso (0xDC00..0xDFFF) deve essere immediatamente preceduto da un surrogato alto (0xD800..0xDBFF).
  • Regola 4 (non-caratteri): i non-caratteri (come U+FDD0..U+FDEF, U+FFFE, U+FFFF) sono valori scalari Unicode validi e non devono mai essere trattati come errori di surrogazione.
Unità di codice (hex) Classificazione dell'errore Offset dell'errore Diagnostica di conformità allo standard Rischio di sicurezza e di analisi
D800 UNPAIRED_HIGH_SURROGATE Posizione 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 Posizione 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 Posizione 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 Posizione 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 Posizione 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 Posizione 1 Valid ASCII A (0041) followed by high surrogate D83D truncated before its low surrogate. Buffer cutoff at surrogate boundary.

Concetti fondamentali e architettura

Distinzioni essenziali per implementare e fare debug correttamente delle stringhe UTF-16 nel software moderno.

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.

Standard autorevoli e riferimenti normativi

Tutti i dati, i calcoli sui surrogati, le regole di buona formazione e gli ordini di serializzazione dei byte di questa pagina derivano direttamente da standard tecnici normativi:

  • 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))