Español

Herramientas de desarrollo · Codificador y decodificador Base64

Decodificación de Base64 a UTF-8 sin mojibake: atob más TextDecoder

· Cómo funciona

base64 codificación Unicode

Tubería desde Base64 a UTF-8 que muestra fallas de mojibake
Ilustración de vector original de ToolAcre

atob() devuelve bytes disfrazados de caracteres, razón por la cual el texto acentuado parece roto después de la decodificación. Esta publicación muestra la canalización correcta desde Base64 a bytes a texto UTF-8 y cómo reconocer el patrón de falla.

La respuesta API que decodifica a 'Café': un síntoma concreto de mojibake y los dos bytes detrás de los dos caracteres incorrectos.

Una cadena Base64 Q2Fmw6k= decodifica en bytes (67, 97, 102, 195, 169), que son UTF-8 texto Café. Pegue en un decodificador ingenuo (solo conversión de atob y cadena) y la salida suele ser Café, cada acento reemplazado por dos caracteres incorrectos. Este mojibake ocurre porque atob devuelve una cadena de bytes (unidades de código 0–255), no texto UTF-8. Los bytes 195 y 169 codifican é acentuada en UTF-8.

Tratarlos como si fueran caracteres latinos separados 1 que proporcionaran un patrón mojibake. La canalización correcta es atob (bytes como cadena), luego TextDecoder (interpreta bytes como UTF-8) y regresa el texto original. La función atob no está rota; está diseñado para datos binarios. Su nombre proviene de ASCII a binario y la cadena binaria que produce es una secuencia de unidades de código 0–255, cada una de las cuales representa un byte.

Lo que atob() realmente devuelve: una cadena de unidades de código 0–255 que representan bytes, no texto decodificado.

Si lo alimenta con Q2Fmw6k= (Base64 estándar), genera una cadena donde cada carácter es un byte: unidad de código 67, luego 97, luego 102, luego 195, luego 169. Si muestra esa cadena directamente o la interpreta como texto latino-1, verá un resultado confuso. El paso que falta es convertir las unidades de código en una matriz de bytes y luego decodificar la matriz como UTF-8.

El bucle charCodeAt recupera valores de bytes: para cada carácter en la salida atob, llame a charCodeAt para obtener la unidad de código (número 0–255), guárdela en Uint8Array. Una vez que exista una matriz de bytes, pase a TextDecoder con el juego de caracteres utf-8. TextDecoder lee la secuencia de bytes y la interpreta como texto UTF-8, combinando secuencias de bytes como (195, 169) en caracteres individuales como é. Los bytes (67, 97, 102, 195, 169) se convierten en una cadena de cuatro caracteres Café. El bucle es deliberadamente aburrido: lea cada unidad de código devuelta con charCodeAt y asígnela a la posición Uint8Array correspondiente. Allí no se produce ninguna decisión sobre el conjunto de caracteres. La única interpretación llega cuando TextDecoder recibe esa matriz y aplica UTF-8 con manejo de errores fatales.

Convertir esa cadena en un Uint8Array: el bucle charCodeAt y por qué es una copia de bytes, no una conversión

Este proceso de dos pasos (recuperación de bytes y luego interpretación UTF-8) es lo que hace internamente el codificador y decodificador Base64. El patrón mojibake es un signo revelador de este error. Si Café aparece como Café, está viendo la interpretación latina-1 de UTF-8 bytes. UTF-8 bytes para é son 0xC3 0xA9 (decimal 195, 169). En latín-1, la unidad de código 195 es Ã, y la unidad de código 169 es ©.

Cuando la secuencia de bytes UTF-8 se lee como si cada byte fuera un carácter latino 1 independiente, cada secuencia UTF-8 de varios bytes produce caracteres de reemplazo incorrectos. ¿Si Café aparece como Caf seguido de personaje de reemplazo, o como Caf? o Caf más U+FFFD, está viendo una falla diferente: el decodificador no reconoció la secuencia de bytes como UTF-8 válida. Un ejemplo concreto: Base64 SGVsbG8sIOS4lueVjCEg8J-Zgg== decodifica de la siguiente manera.

TextDecoder y la decisión del juego de caracteres: decodificación como UTF-8 y por qué el juego de caracteres es un hecho separado que debes saber

atob produce una cadena binaria con bytes (72, 101, 108, 108, 111, 44, 32, 228, 184, 180, 149, 140, 33, 32, 240, 159, 152, 130). Los primeros seis bytes son ASCII: se convierten en Hola. Los bytes 228, 184, 180 son una secuencia UTF-8 de tres bytes que representa el carácter CJK. Los bytes 149, 140 son parte de la siguiente secuencia. La secuencia completa incluye una secuencia de emoji de cuatro bytes (240, 159, 152, 130) para el carácter final.

Cuando se procesa correctamente a través de TextDecoder, todos los bytes se combinan para producir texto original en escritura mixta. Las secuencias de bytes UTF-8 tienen longitudes predecibles: el byte que comienza con 0xxxxxxx es ASCII de un solo byte; el byte que comienza con 110xxxxx espera el siguiente byte que comienza con 10xxxxxx (dos bytes en total); el byte que comienza con 1110xxxx espera dos bytes siguientes (tres bytes en total); El byte que comienza con 11110xxx espera tres bytes siguientes (cuatro bytes en total). Para una muestra mixta de CJK y emoji, la vista de bytes es particularmente diagnóstica porque la intuición ASCII ya no ayuda. Varios bytes pertenecen a cada símbolo visible y una eliminación de un byte cambia la secuencia restante a UTF-8 no válida. Una decodificación estricta convierte ese cambio en un fracaso con nombre en lugar de un daño aparentemente plausible.

Ejemplo resuelto: decodificar una cadena Base64 que contiene CJK y un emoji: bytes, puntos de código y la cadena final en comparación con el original

La secuencia que comienza con 1111110x no es válida en UTF-8 (reservada para el futuro, no utilizada). El byte que comienza con 10xxxxxx nunca debe aparecer como byte inicial; es continuación. Si el flujo de bytes viola las reglas, no es válido UTF-8. TextDecoder con juego de caracteres utf-8 interpreta la matriz según estas reglas y tiene éxito en secuencias válidas. Si no es válido, informa error.

El codificador y decodificador Base64 utiliza TextDecoder con el indicador de modo estricto verdadero. Esto significa que UTF-8 no válido genera un error en lugar de insertar silenciosamente caracteres de reemplazo (U+FFFD). Si la cadena Base64 se decodifica en bytes que no son válidos UTF-8, se iniciará el modo estricto en lugar de continuar con texto confuso. Esta es una elección de diseño: las cargas útiles binarias (imágenes, claves, datos comprimidos) no son texto y no deben decodificarse como texto.

Reconocer el patrón: Ã, †y � — cómo distinguir un problema Base64 de un problema de conjunto de caracteres

Si intenta decodificar JPEG como Base64, el flujo de bytes no representará un UTF-8 válido y la decodificación estricta lo rechazará. La herramienta ofrece vista hexadecimal para dichas cargas útiles: puede ver bytes sin procesar sin pretender que sean texto. Reconocer los errores de decodificación UTF-8 implica mirar los bytes en contexto. ¿Son números impares donde se espera una secuencia de varios bytes?

¿El primer byte de la secuencia potencial no es válido (comenzando con 10xxxxxx)? ¿Faltan bytes de continuación? El botón de salida de bytes proporciona la bifurcación más limpia de la investigación. Si aparece hexadecimal pero falla la decodificación del texto, el análisis Base64 se realizó correctamente y la carga útil es binaria, está dañada o está codificada con un juego de caracteres diferente. Cambiar la puntuación Base64 no puede reparar una discrepancia en el juego de caracteres después de que ya surgieron los bytes correctos.

Lo que esto no cubre: cargas útiles UTF-16, salida binaria como imágenes y manejo de bytes no válidos

Los patrones son consistentes. Un solo byte 0xFF nunca es válido en UTF-8; no puede ser un byte ASCII (solo 0–127 son ASCII) y no puede ser un byte inicial (los bytes principales son 0xC0–0xFD, 0xFF está reservado). Los sustitutos solitarios (concepto UTF-16) no pueden aparecer en UTF-8; Si ve la secuencia de bytes 0xED 0xA0 0x80 (que codifica el sustituto U+D800 en el estilo UTF-8), no es válido UTF-8.

Una solución histórica es btoa(unescape(encodeURIComponent(text))). encodeURIComponent convierte café en %C3%A9 (codificación porcentual UTF-8 bytes), vuelve a empaquetar sin escape como unidades de código, btoa codifica unidades de código. Esto funciona para la mayoría de los textos, pero es frágil con sustitutos solitarios y difícil de leer. La canalización moderna (TextEncoder a bytes y luego base64) es más clara y estándar. TextEncoder está integrado en todos los navegadores modernos y en Node.js, lo que permite tomar la decisión correcta. UTF-16, las codificaciones heredadas de un solo byte y el contenido de archivos arbitrarios requieren un descodificador seleccionado para esos bytes o un visor con reconocimiento binario. ToolAcre intencionalmente no adivina entre ellos. Adivinar podría convertir una secuencia no válida en texto engañoso, mientras que un volcado hexadecimal preserva cada byte para una interpretación informada posterior.

Conclusión: Base64 le proporciona bytes, UTF-8 le proporciona texto: cómo el codificador y descodificador Base64 realiza ambos pasos para que el texto decodificado coincida exactamente con la entrada

Cuando tiene una cadena Base64 y desea texto UTF-8, los pasos completos son: decodificar Base64 en bytes (usando atob o la biblioteca de decodificación base64), crear Uint8Array a partir de bytes, pasar la matriz a TextDecoder con el conjunto de caracteres utf-8, leer el resultado como una cadena.

Si la entrada son datos binarios en lugar de texto, omita TextDecoder y examine los bytes directamente. El codificador y decodificador Base64 proporciona una vista de bytes hexadecimales, preservando valores que la decodificación estricta UTF-8 rechazaría. Esa bifurcación es diagnóstica: los bytes exitosos más el texto fallido significan que el análisis Base64 funcionó, mientras que la carga útil es binaria, está dañada o codificada con un juego de caracteres que esta herramienta no adivina.