Base64 é um jeito de escrever bytes arbitrários — uma imagem, uma chave, um arquivo zip — usando apenas 64 caracteres de texto puro, para que os dados sobrevivam a canais que foram feitos para texto e estragam qualquer outra coisa. Funciona em blocos: entram três bytes, saem quatro caracteres, o que deixa o resultado cerca de um terço maior do que aquilo com que você começou. É uma codificação, não criptografia. Qualquer pessoa que veja a string consegue reverter em um segundo, sem chave e sem senha.
Como o Base64 funciona de verdade?
Três bytes são 24 bits. O Base64 corta esses 24 bits em quatro grupos de seis. Seis bits guardam um número de 0 a 63, e cada número corresponde a um caractere de um alfabeto fixo: A–Z para 0–25, a–z para 26–51, os dígitos 0–9 para 52–61, e depois + e /. Vinte e seis mais vinte e seis mais dez mais dois dão sessenta e quatro, e é daí que vem o nome.
Pegue a palavra Man. Esses três bytes são 01001101 01100001 01101110. Reagrupados de seis em seis, eles ficam 010011, 010110, 000101, 101110 — ou seja, 19, 22, 5 e 46. Procure cada número no alfabeto e você obtém TWFu. Sem compressão, sem chave. Os mesmos bits, fatiados de outro jeito.
Por que tantas strings Base64 terminam em sinais de =?
A entrada quase nunca é um múltiplo exato de três bytes. Quando não é, o codificador completa o último grupo com bits zero e registra o que faltou com caracteres =. Um = significa que o último grupo tinha dois bytes; dois deles significam que tinha um. A letra sozinha M vira TQ==. Você nunca vai ver três caracteres de preenchimento, porque três bytes faltando não formam grupo parcial nenhum.
Essa também é a checagem mais rápida em uma string que alguém te entregou. Para ver o que tem de fato dentro de uma, o codificador e decodificador Base64 daqui tira os espaços em branco, devolve o preenchimento que falta e recusa um comprimento que não pode estar certo em vez de entregar besteira em silêncio. Ele aceita texto colado, não arquivos — não existe seletor de arquivo, e um arquivo binário jogado dentro de uma caixa de texto já está arruinado — e roda na aba, então um token que você está depurando nunca sai do seu computador.
Por que o Base64 existe, afinal?
Porque boa parte da infraestrutura foi projetada para texto e quebra com bytes crus. O e-mail é o caso original: o SMTP foi especificado para ASCII de 7 bits, então um arquivo cheio de bytes arbitrários de 8 bits não podia simplesmente ser jogado dentro de uma mensagem. O MIME, o padrão que permite que o correio carregue qualquer coisa além de texto puro, definiu o Base64 como uma de suas codificações de transferência no início dos anos 1990, e é assim que todo anexo que você envia viaja até hoje.
O mesmo problema volta sempre com roupa nova. JSON não tem tipo binário nenhum — uma string precisa ser texto válido, e um byte de controle cru no meio de uma não é. Um arquivo de configuração YAML, um documento XML, uma coluna de texto num banco de dados, uma linha de log: todos aceitam os 64 caracteres do Base64 sem reclamar, e todos fazem algo imprevisível com o byte 0x00. O Base64 é a resposta chata e universal. Faça os bytes parecerem texto e o canal de texto para de se importar com o que eles são.
Onde você esbarra em Base64?
- Anexos de e-mail. Quebrados a cada 76 caracteres por linha, porque o SMTP nunca prometeu que algo mais longo chegaria intacto.
- Data URIs.
data:image/png;base64,…coloca um arquivo inteiro dentro de um arquivo HTML ou CSS. Útil para um ícone minúsculo, caro para qualquer outra coisa — quando embutir uma imagem realmente compensa é uma pergunta mais estreita do que parece. - JSON Web Tokens. O header e o payload são base64url, e é por isso que você consegue ler um JWT sem chave nenhuma.
- Autenticação HTTP Basic. O header
AuthorizationcarregaBasicseguido do Base64 deusuario:senha. Isso é ofuscação, não proteção, e é a razão pela qual Basic auth sem HTTPS equivale a mandar a senha em texto puro. - Arquivos PEM. Certificados e chaves privadas são Base64 quebrado a cada 64 caracteres entre as linhas BEGIN e END.
- Valores opacos de API. Cursores de paginação, IDs de upload, cookies assinados. Decodificar um costuma revelar um timestamp e um ID de registro que alguém achou que ninguém iria olhar.
O que é base64url e por que os tokens usam isso?
A RFC 4648 define dois alfabetos, e o segundo existe porque o primeiro é hostil dentro de uma URL. Um + numa query string é lido como espaço pelos decodificadores de formulário, uma / encerra um segmento de caminho, e o preenchimento = precisa ser escapado. O base64url mantém os primeiros 62 caracteres, troca os dois últimos por - e _, e normalmente descarta o preenchimento.
Os bits por baixo são idênticos, e é justamente isso que torna a confusão cara. Duas strings diferem só onde um + ou uma / caiu, então elas parecem iguais à primeira vista, e um token que decodifica limpo em uma biblioteca e sai como lixo em outra geralmente cruzou essa fronteira. É também por isso que uma string do alfabeto padrão colada num parâmetro de query volta com espaços no lugar dos sinais + — apenas um canto da bagunça maior, aquela que o URL encoding existe para limpar.
Por que Base64 não é criptografia, nem compressão
Não há chave, não há segredo e não há trabalho nenhum em reverter. Uma senha guardada em Base64 num arquivo de configuração é uma senha em texto puro usando fantasia: ela barra um olhar casual e nada mais.
Os JWTs pegam as pessoas de surpresa pelo mesmo motivo. As claims de um token são assinadas, não escondidas: a assinatura mostra que o payload não foi alterado, e não mostra nada sobre quem está com ele. Qualquer um que tenha o token, inclusive o próprio usuário, cujo navegador o está armazenando, consegue ler todos os campos. Cole um num decodificador de JWT e os IDs internos de usuário, os endereços de e-mail e as flags de papel saem na hora. O que um JWT realmente contém cobre o resto, inclusive as partes que são genuinamente protegidas.
Também não é compressão. Codificar um arquivo zip em Base64 deixa ele um terço maior, não menor. Comprima primeiro e codifique depois, nunca ao contrário: o Base64 desloca as sequências repetidas para fora do alinhamento de bytes, porque os mesmos três bytes viram caracteres diferentes dependendo de onde começam no fluxo. Um compressor rodado sobre o texto codificado acha muito menos com o que trabalhar do que um rodado sobre os bytes originais.
Quanto custa de fato esse acréscimo de 33%?
Quatro caracteres para cada três bytes é um custo fixo, e as quebras de linha somam um pouco mais por cima. Um anexo de 5 MB viaja como uns 6,7 MB de Base64. Uma logo de 40 KB embutida como data URI acrescenta cerca de 53 KB ao arquivo HTML e, ao contrário de uma imagem separada, não pode ser cacheada por conta própria nem buscada em paralelo.
O gzip recupera um pouco disso, já que a saída só usa 64 caracteres distintos, mas não te leva ao tamanho dos bytes crus. Se um transporte consegue carregar binário, carregue binário. O Base64 só vale o que custa quando o canal genuinamente não consegue.
O que costuma quebrar?
Caracteres acentuados e emoji. O btoa() do navegador não aceita texto. Ele aceita uma binary string, em que cada caractere precisa caber em um único byte, e qualquer coisa acima de U+00FF lança InvalidCharacterError. Inglês simples passa em todos os testes que você escrever, e o primeiro cliente chamado Zoë quebra a produção. Converta o texto para bytes UTF-8 e codifique esses bytes — o TextEncoder faz isso no navegador, e Python e Node fazem por padrão.
Preenchimento faltando. Muitos decodificadores, inclusive o deste site, restauram para você. Muitas bibliotecas estritas recusam. Se um token base64url decodifica numa página web e falha no seu código, é a primeira coisa a checar.
Quebras de linha. Os decodificadores deveriam ignorá-las e a maioria ignora, mas alguns parsers embarcados e corporativos antigos não. Um blob copiado de um e-mail é a origem de sempre.
Codificação dupla. Codificar uma string já codificada é válido, silencioso, e faz os dados crescerem mais um terço. Você descobre quando o resultado decodificado é, ele mesmo, Base64.
Esperar texto na saída. Se os bytes originais eram uma imagem, a saída decodificada é ruído, e um decodificador tolerante te mostra mojibake em vez de um erro. Nada está quebrado; o payload nunca foi texto.
Quando você deveria usar outra coisa?
O Base64 responde a uma pergunta só: como eu movo bytes por um canal que aceita apenas texto. Se você precisa esconder algo, use criptografia; se precisa encolher, comprima. E se o problema real é que alguns poucos caracteres têm significado estrutural no documento ao redor, um escape mais estreito ganha de codificar tudo — entidades HTML para markup, percent-encoding para URLs, aspas padrão para CSV. Esses mantêm o conteúdo legível, que é justamente o que o Base64 destrói por design.
O jeito mais rápido de tornar tudo isso concreto é passar uma string por ele. O codificador e decodificador Base64 lê os dois alfabetos, restaura o preenchimento que falta, conta os bytes que entram contra os caracteres que saem, e acerta o UTF-8, então o texto acentuado que quebra o btoa() sobrevive intacto à ida e volta. Ele funciona com texto colado em vez de arquivos, o que cobre tokens, chaves e valores de configuração, mas não um PDF.
Se você chegou aqui porque uma string num arquivo de configuração ou numa URL não estava fazendo o que você esperava, o problema vizinho costuma ser escaping e não codificação. Entidades HTML: quando você precisa delas e quando não cobre a outra metade disso — quais caracteres precisam ser escapados, quais as pessoas escapam por superstição, e o que a diferença custa.
Perguntas frequentes
Para que serve o Base64?
Serve para mover dados binários por canais que só aceitam texto: anexos de e-mail, data URIs dentro de HTML e CSS, JSON Web Tokens, arquivos de certificado PEM e headers de autenticação HTTP Basic. Em todos os casos o ponto é que o sistema que recebe corromperia ou rejeitaria os bytes crus. O Base64 reescreve esses bytes usando 64 caracteres que qualquer canal de texto carrega sem alterar.
Base64 é criptografia?
Não. O Base64 não tem chave nem segredo, e qualquer pessoa que veja a string consegue decodificar na hora com uma ferramenta gratuita ou uma linha de código. É uma codificação, feita para transporte, não para privacidade. Uma senha guardada em Base64 é uma senha em texto puro com um passo a mais.
Por que o Base64 deixa os arquivos maiores?
Porque ele transforma cada três bytes em quatro caracteres, o que é um aumento fixo de 33%, e a quebra de linhas soma um pouco mais. Um arquivo de 5 MB vira cerca de 6,7 MB de Base64. É por isso que você comprime um arquivo antes de codificar, nunca depois.
O que significam os sinais = no fim de uma string Base64?
São preenchimento, adicionado quando o comprimento da entrada não era múltiplo de três bytes. Um = significa que o grupo final tinha dois bytes, e dois = significam que tinha um. Uma string válida nunca termina em três caracteres de preenchimento. Algumas variantes, incluindo o base64url usado nos JWTs, descartam o preenchimento por completo.
Como eu sei se uma string é Base64?
Você não tem como ter certeza, só descartar. O Base64 usa A–Z, a–z, 0–9 e mais dois caracteres, e o comprimento com preenchimento é múltiplo de quatro, então qualquer coisa fora desse conjunto não é Base64. Mas palavras comuns também passam no teste: "test" é uma string Base64 válida que decodifica para três bytes de lixo binário. Decodificar e olhar o resultado é a única checagem de verdade.
Por que o btoa() falha com caracteres acentuados?
btoa() espera uma binary string, em que cada caractere é um único byte, então qualquer coisa acima de U+00FF lança InvalidCharacterError. Acentos e emoji ficam acima desse limite. Converta o texto para bytes UTF-8 com o TextEncoder primeiro, depois codifique esses bytes, e o resultado vai bater com o que Python e Node produzem.
Última atualização 19 de setembro de 2026