Skip to content

Glossary

UTF-8

La codificación de caracteres de la web

By Published Updated

UTF-8 (Unicode Transformation Format, 8 bits) es una codificación de ancho variable para caracteres Unicode. Cada punto de código se codifica en 1-4 bytes dependiendo de su valor: los caracteres ASCII (U+0000 a U+007F) ocupan un byte; las extensiones latinas comunes, el griego y el cirílico, dos; los ideogramas CJK, tres; los emoji y los scripts raros, cuatro.

Diseñado por Ken Thompson y Rob Pike en 1992, principalmente para Plan 9. Propiedades clave:

  • Compatible con ASCII. El texto ASCII puro es UTF-8 válido byte a byte.
  • Autosincronizante. Si un flujo de datos se corrompe en medio de un carácter, el decodificador puede encontrar el siguiente límite de carácter sin retroceder.
  • Sin problema de orden de bytes. Los bytes se procesan de izquierda a derecha; no hay distinción entre big-endian y little-endian.
  • Compacto para scripts latinos, menos compacto que UTF-16 para contenido con predominio de CJK (3 bytes por carácter frente a 2).

UTF-8 es la codificación dominante en la web — más del 98 % de las páginas en 2024. Es el predeterminado para HTML5, JSON (donde la especificación RFC 8259 exige UTF-8) y prácticamente todos los protocolos modernos. Las codificaciones antiguas (Windows-1252, ISO-8859-1, Shift-JIS) sobreviven en sistemas heredados, pero deben convertirse al ingresar a cualquier pila moderna.

La controversia del BOM (marca de orden de bytes): UTF-16 y UTF-32 usan un BOM de 2 o 4 bytes al inicio de un archivo para declarar el orden de bytes, pero UTF-8 no tiene orden de bytes que marcar. Las herramientas de Microsoft habitualmente añaden un BOM UTF-8 de 3 bytes (EF BB BF) de todas formas, mientras que las herramientas de Unix típicamente no lo hacen. El resultado: los scripts de shell guardados desde Notepad fallan, las importaciones de CSV muestran basura invisible en la primera celda y los analizadores YAML/JSON rechazan el archivo. El estándar Unicode tolera pero no exige un BOM UTF-8; la recomendación moderna es “no añadir uno.” Si recibes un archivo con uno, elimínalo al leerlo.

Longitud de cadena frente a longitud en bytes — la trampa siempre relevante: en la mayoría de los lenguajes, "hello".length devuelve 5 (caracteres) pero Buffer.byteLength("hello", "utf8") devuelve 5 (bytes, iguales para ASCII). Para "café", la longitud en caracteres es 4 pero la longitud en bytes es 5 (la é ocupa 2 bytes). Para "🎉", la longitud en caracteres en JavaScript es 2 (par sustituto), pero la longitud en bytes es 4 y la longitud en grafemas es 1. Truncar cadenas UTF-8 por número de bytes sin conciencia de grafemas produce regularmente mojibake — la solución estándar es usar la API Intl.Segmenter (navegadores modernos) o el paquete npm graphemer. Referencia: RFC 3629 — UTF-8, un formato de transformación de ISO 10646.

Ejemplo práctico

Codifica la cadena “A€🎉”. El punto de código de cada carácter y su secuencia de bytes UTF-8: A (U+0041) → 1 byte 0x41. € (U+20AC) → 3 bytes 0xE2 0x82 0xAC (los bits altos codifican la longitud: 1110xxxx 10xxxxxx 10xxxxxx). 🎉 (U+1F389) → 4 bytes 0xF0 0x9F 0x8E 0x89. Total: 8 bytes para 3 caracteres. En una columna de base de datos declarada como VARCHAR(10) con semántica de caracteres UTF-8 (PostgreSQL moderno, MySQL con utf8mb4), cabe perfectamente. En una columna de bytes fijos declarada como VARCHAR(10) BYTES (MySQL antiguo con utf8, que en realidad estaba limitado a 3 bytes), la codificación de 4 bytes del emoji no cabe en absoluto — el modo de fallo canónico de “no se pueden almacenar emoji en MySQL”. La solución en MySQL desde 5.5.3 es usar utf8mb4 como conjunto de caracteres de la columna y la conexión.

Cuándo y por qué importa

Cada byte que procesas en la web moderna es probablemente UTF-8, pero varias capas aún lo gestionan mal. Las solicitudes HTTP sin un Content-Type: text/...; charset=utf-8 explícito pueden usar ISO-8859-1 de forma predeterminada en proxies más antiguos; los trabajos ETL de mainframe heredados entregan archivos EBCDIC que deben transcodificarse al ingresar; la salida de la consola de Windows usa de forma predeterminada la página de códigos del sistema (CP-1252 en la mayoría de las instalaciones en inglés de EE. UU.) y corrompe el texto canalizado sin un chcp 65001 previo. La práctica defensiva: declarar UTF-8 explícitamente en todas partes (HTML <meta charset="utf-8">, encabezados HTTP, pragmas de codificación de archivos, conjuntos de caracteres de conexión a bases de datos) y validar cualquier byte entrante contra la gramática UTF-8 — las secuencias de bytes inválidas son una señal fiable de una discrepancia de charset aguas arriba. Referencia: Estándar de codificación WHATWG.

Frequently asked questions

¿Qué es UTF-8?
UTF-8 es una codificación Unicode de ancho variable que representa cada punto de código usando entre 1 y 4 bytes. Los caracteres ASCII (U+0000 a U+007F) usan exactamente 1 byte, lo que hace que UTF-8 sea totalmente retrocompatible con ASCII. Es la codificación dominante en la web, usada por más del 98 % de las páginas.
¿Cómo funciona la codificación UTF-8 en la práctica?
La letra latina A (U+0041) se almacena como un único byte 0x41. El emoji de cara sonriente (U+1F600) requiere 4 bytes: 0xF0 0x9F 0x98 0x80. Este diseño significa que el texto en inglés almacenado como ASCII también es UTF-8 válido, y el texto multilingüe se maneja añadiendo más bytes solo cuando es necesario.
¿Cuál es la diferencia entre UTF-8 y UTF-16?
UTF-8 usa entre 1 y 4 bytes y es compatible con ASCII, lo que lo hace ideal para la web y el almacenamiento de archivos. UTF-16 usa 2 o 4 bytes y es común en los internos de Windows y Java. UTF-8 es más eficiente en espacio para texto con predominio de ASCII; UTF-16 usa los mismos 2 bytes para la mayoría de los caracteres CJK comunes, mientras que UTF-8 usa 3.

Related

Published May 14, 2026 · Last reviewed May 31, 2026