¿Qué es la Codificación Unicode?
Unicode es un estándar universal de codificación de caracteres que asigna un número único — llamado punto de código — a cada carácter utilizado en los lenguajes humanos. Antes de Unicode, había docenas de sistemas de codificación incompatibles. Un documento escrito en ruso en un sistema era ilegible en otro. Unicode resuelve esto proporcionando un conjunto de caracteres único y unificado que cubre más de 150 sistemas de escritura y 140,000 caracteres.
Unicode en sí mismo no es una codificación. Es un repertorio de caracteres. La capa de codificación — cómo se almacenan los puntos de código como bytes — es manejada por formas de codificación como UTF-8, UTF-16 y UTF-32. Entender la distinción entre un punto de código y su representación en bytes es la clave para evitar errores de codificación.
Puntos de Código
Cada carácter Unicode tiene un punto de código escrito como U+ seguido de un número hexadecimal. La letra A es U+0041, el signo del euro es U+20AC, y el emoji 😀 es U+1F600.
Los puntos de código están organizados en 17 planos, cada uno conteniendo 65,536 caracteres. El primer plano (Plano 0) es el Plano Multilingüe Básico (BMP), que contiene los caracteres más comunes incluyendo latín, griego, cirílico, CJK y muchos otros. Los Planos 1 al 16 contienen caracteres suplementarios como emojis, escrituras históricas y caracteres CJK raros.
| Plano | Rango | Nombre |
|---|---|---|
| 0 | U+0000 a U+FFFF | Plano Multilingüe Básico (BMP) |
| 1 | U+10000 a U+1FFFF | Plano Multilingüe Suplementario (SMP) |
| 2 | U+20000 a U+2FFFF | Plano Ideográfico Suplementario (SIP) |
| 3-13 | U+30000 a U+DFFFF | No asignados |
| 14 | U+E0000 a U+EFFFF | Plano Suplementario de Propósito Especial (SSP) |
| 15-16 | U+F0000 a U+10FFFF | Planos de Uso Privado |
UTF-8, UTF-16, UTF-32
Estas tres formas de codificación difieren en cómo mapean los puntos de código a bytes.
UTF-8
UTF-8 es la codificación dominante en la web. Usa de 1 a 4 bytes por carácter y es compatible hacia atrás con ASCII. Los caracteres en el rango ASCII (U+0000 a U+007F) usan un byte. Los alfabetos europeos usan dos bytes. Los caracteres CJK y emojis usan tres o cuatro bytes.
| Rango de Punto de Código | Byte 1 | Byte 2 | Byte 3 | Byte 4 |
|---|---|---|---|---|
| U+0000 - U+007F | 0xxxxxxx | |||
| U+0080 - U+07FF | 110xxxxx | 10xxxxxx | ||
| U+0800 - U+FFFF | 1110xxxx | 10xxxxxx | 10xxxxxx | |
| U+10000 - U+10FFFF | 11110xxx | 10xxxxxx | 10xxxxxx | 10xxxxxx |
Ventajas de UTF-8:
- El texto ASCII es UTF-8 válido (no necesita conversión)
- Autosincronizable: siempre puedes encontrar los límites de los caracteres
- Sin problemas de orden de bytes (little-endian / big-endian)
- Más eficiente en espacio para textos con alfabeto latino
UTF-16
UTF-16 usa 2 bytes (una unidad de código) para caracteres BMP y 4 bytes (dos unidades de código, llamados pares sustitutos) para caracteres suplementarios. Windows, Java y JavaScript usan UTF-16 internamente.
UTF-16 tiene problemas de orden de bytes. Un archivo UTF-16 debe especificar si es little-endian (UTF-16LE) o big-endian (UTF-16BE), típicamente usando una BOM (Marca de Orden de Bytes) al inicio.
UTF-32
UTF-32 usa exactamente 4 bytes para cada punto de código. Es simple pero derrochador. Un archivo puramente ASCII se vuelve cuatro veces más grande. UTF-32 rara vez se usa en la práctica.
Comparación
| Característica | UTF-8 | UTF-16 | UTF-32 |
|---|---|---|---|
| Bytes por carácter | 1-4 | 2 o 4 | 4 |
| Compatibilidad con ASCII | Sí | No | No |
| Uso en la web | ~98% | ~2% | <0.01% |
| BOM necesaria | No | Sí | Sí |
| Común en | Web, Linux, JSON | Windows, Java, JS | Procesamiento interno |
Errores de Codificación
El error de codificación más común es tratar bytes como caracteres. Cuando tomas una cadena UTF-8 y la interpretas como Latin-1 (ISO 8859-1), los caracteres acentuados aparecen como símbolos confusos. Esto sucede cuando la codificación no se declara o cuando una herramienta asume la codificación incorrecta.
Otro problema común es contar bytes en lugar de caracteres. En UTF-8, la cadena "café" tiene 4 caracteres pero 5 bytes porque é usa dos bytes. Funciones como strlen de PHP cuentan bytes por defecto, mientras que mb_strlen cuenta caracteres.
Ejemplos de Programación
// PHP - usar siempre funciones mb_* para UTF-8
$text = 'café ☕';
echo strlen($text); // 8 bytes (recuento incorrecto)
echo mb_strlen($text, 'UTF-8'); // 6 caracteres
// Codificar/decodificar puntos de código Unicode
echo mb_convert_encoding($text, 'UTF-16', 'UTF-8');
# Python 3 - las cadenas son Unicode por defecto
text = 'café ☕'
print(len(text)) # 6 caracteres
bytes_utf8 = text.encode('utf-8')
bytes_utf16 = text.encode('utf-16')
print(bytes_utf8) # b'caf\xc3\xa9 \xe2\x98\x95'
// JavaScript - las cadenas son UTF-16 internamente
let text = 'café ☕';
console.log(text.length); // 6 (pero el emoji puede contar como 2)
// Codificar como bytes UTF-8
let encoder = new TextEncoder();
let bytes = encoder.encode(text);
console.log(bytes); // Uint8Array(8)
Herramienta en Línea
La herramienta Codificador y Decodificador Unicode en Help2Code convierte texto a puntos de código Unicode y entre representaciones UTF-8, UTF-16 y UTF-32. Es útil para depurar problemas de codificación y aprender cómo funciona Unicode.
Conclusión
La codificación Unicode es un conocimiento esencial para cualquier desarrollador que trabaje con texto internacional. UTF-8 es el estándar para la web y debe ser tu opción predeterminada. Entender la diferencia entre puntos de código y representaciones en bytes te ayudará a evitar los errores de codificación de texto más comunes. Usa la herramienta Codificador y Decodificador Unicode para experimentar con codificaciones y depurar problemas de codificación.