Saltar al contenido
AZ Tools

Por qué tu texto se convierte en caracteres extraños

En el disco no existe el texto sin más. Un archivo contiene bytes, y una codificación es el acuerdo que dice qué byte o grupo de bytes representa cada carácter. Un archivo de texto plano no guarda constancia de ese acuerdo, así que todo programa que lo abre está haciendo una suposición. Cuando la suposición es falsa aparecen los caracteres raros, y la forma concreta del estropicio es una pista fiable de lo que ocurrió.

La basura tiene firmas que conviene reconocer

La más conocida es la letra acentuada que se convierte en dos. En UTF-8 la letra é se guarda como los bytes C3 y A9, y un programa que los lee de uno en uno con una página de códigos de Europa occidental imprime à y ©. Cualquier archivo UTF-8 leído con una codificación antigua de un solo byte convierte así cada carácter no inglés en dos o tres, y esa ristra es lo que hace que un texto coreano o japonés parezca un muro de escombros latinos.

Otras tres marcas dicen algo distinto. Un archivo que empieza por  es UTF-8 con marca de orden de bytes leído como otra cosa. El rombo negro con un signo de interrogación es el carácter de reemplazo, que el decodificador escribe cuando los bytes no podían ser válidos en la codificación que le indicaron. Y un simple interrogante donde debería haber una letra suele significar que el texto se convirtió a una codificación sin sitio para esa letra.

Dos de esas firmas significan que el texto ya se perdió

é se puede recuperar, porque los bytes originales siguen en el archivo y lo único equivocado es la interpretación. Leer esos mismos bytes con la codificación correcta devuelve el texto exactamente.

El carácter de reemplazo y el interrogante pelado son otra cosa: son lo que el archivo contiene ahora. Los bytes originales se descartaron en el momento de la conversión, y ningún paso posterior puede deducir si ese rombo fue una é o una ü. Por eso la primera regla al reparar un problema de codificación es dejar de guardar encima del archivo: cada guardado con la codificación equivocada convierte un problema reversible en uno irrecuperable.

La doble codificación y por qué se repite

Si un programa lee UTF-8 como si fuera de un solo byte y luego guarda el resultado en UTF-8, el error adquiere aspecto de permanente: el archivo contiene ahora de verdad los caracteres à y ©, cada uno con sus propios dos bytes. Hazlo dos veces y una letra pasa a ser cuatro caracteres, y luego ocho.

Sigue siendo reversible, porque el proceso se invierte exactamente si sabes cuántas rondas hubo: vuelve a codificar a la página de códigos de un byte y decodifica como UTF-8, una vez por ronda. Este patrón aparece tanto porque suele ocurrir dentro de una tubería — un formulario, una columna de base de datos, una exportación — donde la misma conversión se aplica a datos que ya pasaron por ella.

Las codificaciones antiguas que aún te encuentras

El texto occidental suele llegar en Windows-1252, que es lo que la mayoría quiere decir cuando dice Latin-1. La diferencia importa: Windows-1252 rellena con comillas tipográficas, la raya y los puntos suspensivos el rango que Latin-1 deja vacío, y por eso una comilla curva aflora tantas veces como “. El texto de sistemas asiáticos antiguos llega en Shift_JIS, EUC-KR, Big5 o GB18030, y el cirílico en Windows-1251 o KOI8-R.

En una oficina, la fuente habitual es la hoja de cálculo. Exportar un CSV en Windows todavía tiende a escribir la página de códigos del sistema en lugar de UTF-8, así que un archivo impecable en la máquina que lo creó se rompe en todas las demás; y como al reimportarlo allí se ve bien, quien lo hizo no llega a ver el problema.

Detectar es adivinar, y con poco texto es peor

UTF-8 se valida a sí mismo: sus secuencias de varios bytes siguen un patrón estricto, así que un archivo que decodifica limpiamente como UTF-8 casi seguro lo es. Esa es la única respuesta segura que un detector puede dar.

En cambio, cualquier codificación de un solo byte acepta todos los bytes posibles, de modo que nada descarta a ninguna. El detector elige mirando qué letras y qué pares de letras son frecuentes en los idiomas reales, lo que funciona con un párrafo y falla con un nombre o un encabezado de columna. Una herramienta que responde Windows-1252 con poca confianza para veinte bytes está siendo honesta, no inútil.

Dónde se supone que un archivo se declara

Los formatos que llevan declaración son mucho más fáciles de acertar. HTML tiene su meta charset, XML su declaración, y cualquier cosa servida por HTTP puede indicar el juego de caracteres en la cabecera Content-Type, que manda sobre lo que el documento diga de sí mismo: una página correcta servida con una cabecera equivocada se rompe igual.

La marca de orden de bytes al principio de un archivo UTF-8 es otra forma de declaración, y corta por los dos lados. Elimina la adivinanza en los editores que la entienden y estropea las herramientas que no: un analizador de JSON que informa de un carácter inesperado en la posición cero, un script cuya primera línea ya no es un shebang, o un CSV cuyo primer nombre de columna lleva pegado un carácter invisible.

Cómo arreglar de verdad un archivo roto

Trabaja desde los bytes, no desde la pantalla. Mira el archivo en hexadecimal para ver si los caracteres acentuados ocupan uno o dos bytes, porque eso solo ya separa un archivo antiguo de un UTF-8 mal leído. Después prueba a decodificar con una codificación candidata y comprueba que vuelven palabras reales: la prueba es que el texto sea correcto, no que haya cambiado.

Cuando se lea bien, guarda una copia en UTF-8 y deja el original intacto hasta estar seguro. Y arréglalo en la frontera, no en medio: decodifica cuando los datos entran, mantén una sola codificación dentro y decláralo al salir. Los casos que se repiten suelen ser tuberías que convierten en algún punto intermedio, que es justo como un mismo error acaba aplicándose dos veces.

Herramientas relacionadas