Codificación UTF-16
UTF-16 (formato de transformación Unicode de 16 bits) es la codificación de caracteres de anchura variable que representa los valores escalares de Unicode mediante una o dos unidades de código de 16 bits (2 o 4 bytes). Los caracteres del Plano Multilingüe Básico (U+0000 a U+D7FF y U+E000 a U+FFFF) se mapean directamente a una sola unidad de 16 bits. Los caracteres de los planos suplementarios (U+10000 a U+10FFFF)—incluidos los emojis, los alfanuméricos matemáticos y las escrituras históricas—se codifican mediante un par ordenado de unidades de código reservadas llamado par sustituto.
Datos técnicos rápidos
U+0000–U+D7FF & U+E000–U+FFFF
Mapeo escalar directo 1:1 (1 unidad, 2 bytes)
U+D800–U+DFFF
2,048 unidades reservadas; no son caracteres escalares
U+10000–U+10FFFF
Codificados como pares sustitutos (2 unidades, 4 bytes)
U+FEFF)
BE: FE FF | LE: FF FE
Espacio de código y distribución de rangos en UTF-16
El estándar Unicode divide todo el espacio de $1,114,112$ puntos de código en planos. UTF-16 gestiona los puntos de código con unidades de 16 bits simples para los caracteres escalares del BMP y con pares de unidades de 16 bits para los caracteres suplementarios, de acuerdo con la tabla 3-5 del estándar Unicode 17.0.
| Plano de caracteres | Rango escalar | Unidades de código | Longitud en bytes | Rango de unidades de código (hex) | Estado de codificación |
|---|---|---|---|---|---|
|
Basic Multilingual Plane (BMP, Lower)
Covers ASCII, Latin, Greek, Cyrillic, Hebrew, Arabic, and most common scripts.
|
U+0000–U+D7FF |
1 Unidad | 2 Bytes |
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 Unidad | 2 Bytes |
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 Unidad | 2 Bytes |
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 Unidad | 2 Bytes |
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 Unidades | 4 Bytes |
D800 DC00 – DBFF DFFF |
Surrogate Pair Required (High Surrogate + Low Surrogate) |
El mecanismo del par sustituto
Como una sola unidad de código de 16 bits puede direccionar como máximo $65,536$ valores, Unicode reservó $2,048$ unidades de código en el Plano Multilingüe Básico (plano 0) específicamente para codificar los $1,048,576$ caracteres suplementarios (planos 1–16).
0xD800–0xDBFF0xDC00–0xDFFF1. Fórmula de codificación (escalar a sustitutos)
Para cualquier punto de código suplementario $C$ donde $0\text{x}10000 \le C \le 0\text{x}10\text{FFFF}$:
U' = C - 0x10000;HighSurrogate = 0xD800 + (U' >> 10);LowSurrogate = 0xDC00 + (U' & 0x3FF);
Restar $0\text{x}10000$ produce un número de 20 bits ($2^{20} = 1,048,576$). Dividirlo en dos mitades de 10 bits encaja perfectamente en las dos ventanas sustitutas de 1,024 unidades.
2. Fórmula de decodificación (sustitutos a escalar)
Dado un sustituto alto válido $W_1$ y un sustituto bajo $W_2$:
C = 0x10000 + ((W1 - 0xD800) << 10) + (W2 - 0xDC00);
Invierte los desplazamientos de 10 bits y suma el desplazamiento $0\text{x}10000$ para reconstruir el valor escalar Unicode exacto de 21 bits.
Inspector y validador interactivo de UTF-16
Explore en vivo la codificación de unidades de código UTF-16, alterne entre las serializaciones de bytes big-endian y little-endian, o introduzca unidades de código hexadecimales en bruto para validar la conformidad de las secuencias.
D83D DE00
D8 3D DE 00
3D D8 00 DE
0xD83D seguido del sustituto bajo 0xDE00, que juntos decodifican U+1F600. Ejemplo resuelto: codificación de 😀 (U+1F600)
Siga la derivación matemática y de desplazamiento de bits exacta definida por el estándar Unicode 17.0 para convertir el valor escalar suplementario U+1F600 en su par sustituto 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
Verificación por decodificación inversa
C = 0x10000 + ((0xD83D - 0xD800) << 10) + (0xDE00 - 0xDC00)
C = 0x10000 + (0x03D × 1024) + 0x200 = 0x10000 + 0xF400 + 0x200 = 0x1F600 (U+1F600) ✓
La fórmula inversa reconstruye el valor escalar original con una fidelidad matemática del 100 %.
Ejemplos representativos de todos los planos
Caracteres Unicode representativos, símbolos matemáticos, escrituras históricas, marcas combinantes y secuencias complejas de emojis codificadas 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.
Orden de bytes y serialización: UTF-16BE frente a UTF-16LE
UTF-16 define una forma de codificación mediante unidades de código de 16 bits. Cuando estos enteros de 16 bits se serializan en un flujo de bytes de 8 bits (para transmisión por red o almacenamiento), el orden de los dos bytes dentro de cada unidad de código lo gobierna el esquema de codificación: big-endian o little-endian.
| Carácter | Punto de código | Unidades de código de 16 bits | UTF-16BE (big-endian) | UTF-16LE (little-endian) | Comportamiento de serialización |
|---|---|---|---|---|---|
| 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 sobre el intercambio de sustitutos
Al serializar un par sustituto en modo little-endian (UTF-16LE), cada unidad de código de 16 bits se intercambia por bytes individualmente. El orden de las dos unidades de código no cambia: el sustituto alto precede siempre al sustituto bajo. Por ejemplo, D83D DE00 se convierte en 3D D8 00 DE, NO en 00 DE 3D D8.
Semántica de la marca de orden de bytes (BOM)
La marca de orden de bytes (BOM) es el carácter Unicode U+FEFF (ZERO WIDTH NO-BREAK SPACE). Colocada al principio de un flujo UTF-16 serializado, su patrón de bytes revela de inmediato si el flujo es big-endian o little-endian.
El byte de orden superior 0xFE precede al byte de orden inferior 0xFF. Señala un orden de bytes big-endian.
El byte de orden inferior 0xFF precede al byte de orden superior 0xFE. Señala un orden de bytes little-endian.
| Contexto del flujo | Estado del requisito | Explicación según los estándares |
|---|---|---|
| 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. |
El mito del requisito universal
UTF-16 NO exige universalmente un BOM. Aunque es habitual en los archivos de texto de Windows (como los .txt del Bloc de notas etiquetados "Unicode"), los protocolos que especifican charset=utf-16le o charset=utf-16be no requieren explícitamente un BOM. En las aplicaciones web, el estándar de codificación del WHATWG se basa en UTF-8, pero decodifica los flujos etiquetados como UTF-16 según el BOM explícito o las definiciones MIME.
Buena formación y secuencias sustitutas mal formadas
Una secuencia de unidades de código UTF-16 está bien formada si y solo si cada unidad sustituta aparece como parte de una secuencia correctamente emparejada y ordenada. Cualquier sustituto aislado o desemparejado infringe el estándar Unicode 17.0 §3.9 (definición D92).
Invariantes de conformidad de Unicode
- Regla 1 (escalares del BMP): las unidades de código de 16 bits simples deben caer en
U+0000..U+D7FFoU+E000..U+FFFF. - Regla 2 (sustitutos altos): a todo sustituto alto (
0xD800..0xDBFF) debe seguirle inmediatamente un sustituto bajo (0xDC00..0xDFFF). - Regla 3 (sustitutos bajos): a todo sustituto bajo (
0xDC00..0xDFFF) debe precederle inmediatamente un sustituto alto (0xD800..0xDBFF). - Regla 4 (no caracteres): los no caracteres (como
U+FDD0..U+FDEF,U+FFFE,U+FFFF) son valores escalares Unicode válidos y nunca deben tratarse como errores de sustitutos.
| Unidades de código (hex) | Clasificación del error | Desplazamiento del error | Diagnóstico de conformidad estándar | Riesgo de seguridad y del analizador |
|---|---|---|---|---|
D800 |
UNPAIRED_HIGH_SURROGATE | Posición 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 | Posición 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 | Posición 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 | Posición 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 | Posición 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 | Posición 1 |
Valid ASCII A (0041) followed by high surrogate D83D truncated before its low surrogate. | Buffer cutoff at surrogate boundary. |
Conceptos clave y arquitectura
Distinciones esenciales para implementar y depurar correctamente cadenas UTF-16 en el 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.
Codificaciones de caracteres relacionadas
Estándares autoritativos y referencias normativas
Todos los datos, los cálculos de sustitutos, las reglas de buena formación y los órdenes de serialización de bytes de esta página derivan directamente de normas técnicas:
- 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))