Decodex

DECODEX · BASE64 · UTF-8

Base64 em JavaScript com Unicode: corrigir erros de btoa()

Codifique acentos, coreano e emojis com TextEncoder e decodifique com atob e TextDecoder. Código UTF-8 e exemplos verificados.

btoa() recebe uma sequência binária com unidades de código de um byte. Não converte texto para UTF-8 automaticamente. Coreano, hindi e muitos emojis podem causar InvalidCharacterError. Use bytes UTF-8 explícitos para obter uma conversão confiável.

Codificar e decodificar Unicode

TextEncoder transforma texto em bytes. O código abaixo processa blocos pequenos antes de chamar btoa, evitando um argumento para cada byte de um texto grande. Para recuperar o texto, atob gera bytes e TextDecoder os interpreta como UTF-8. A opção fatal detecta bytes inválidos.

Confira a conversão de ida e volta

안녕하세요 😀 produz 7JWI64WV7ZWY7IS47JqUIPCfmIA=. A decodificação precisa recuperar o mesmo texto, espaço e emoji. O link abre o conversor com dados públicos predefinidos, sem colocar texto do usuário na URL. O Decodex converte localmente até 5 MB de texto UTF-8.

Descubra em qual etapa ocorreu o erro

Um erro de atob costuma indicar Base64, preenchimento ou prefixos incorretos. Um erro de TextDecoder pode indicar dados binários ou outra codificação, mesmo com um alfabeto Base64 válido. No Node.js, Buffer.from(text, "utf8").toString("base64") codifica texto, mas a decodificação permissiva não substitui a validação.

Testar este exemplo

// Browser JavaScript: text → UTF-8 bytes → Base64.
function utf8ToBase64(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = '';
  for (let i = 0; i < bytes.length; i += 8192) {
    binary += String.fromCharCode(...bytes.subarray(i, i + 8192));
  }
  return btoa(binary);
}

// Accept standard Base64 or Base64URL, with complete or omitted padding.
function base64ToUtf8(value) {
  let normalized = value.replace(/\s/g, '').replace(/-/g, '+').replace(/_/g, '/');
  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized) ||
      normalized.length % 4 === 1 ||
      (normalized.includes('=') && normalized.length % 4 !== 0)) {
    throw new Error('Invalid Base64 characters, length or padding');
  }
  normalized += '='.repeat((4 - normalized.length % 4) % 4);
  const binary = atob(normalized);
  const bytes = Uint8Array.from(binary, character => character.charCodeAt(0));
  return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
}

const text = '안녕하세요 😀';
const encoded = utf8ToBase64(text);
console.log(encoded); // 7JWI64WV7ZWY7IS47JqUIPCfmIA=
console.log(base64ToUtf8(encoded)); // 안녕하세요 😀

Testar este exemplo →

Base64 → UTF-8 · UTF-8 → Base64

Perguntas frequentes

atob devolve texto legível diretamente?

Não. Ele devolve uma sequência binária. Converta os valores para Uint8Array e use TextDecoder("utf-8"). Prefira esse caminho a funções antigas como unescape().

Referências

Mais guias de Base64