Os 64 caracteres
O Base64 lê a entrada de 3 em 3 bytes (24 bits) e divide cada grupo em quatro números de 6 bits. Cada número, de 0 a 63, é um índice nesta tabela. A ordem é fixada pela RFC 4648: maiúsculas de 0 a 25, minúsculas de 26 a 51, dígitos de 52 a 61 e, por fim, + e /. A última coluna é o código ASCII do caractere, que é o que de fato é armazenado ou transmitido.
| Índice | 6 bits | Base64 | Base64URL | Código ASCII |
|---|---|---|---|---|
| 0 | 000000 | A | A | 0x41 |
| 1 | 000001 | B | B | 0x42 |
| 2 | 000010 | C | C | 0x43 |
| 3 | 000011 | D | D | 0x44 |
| 4 | 000100 | E | E | 0x45 |
| 5 | 000101 | F | F | 0x46 |
| 6 | 000110 | G | G | 0x47 |
| 7 | 000111 | H | H | 0x48 |
| 8 | 001000 | I | I | 0x49 |
| 9 | 001001 | J | J | 0x4A |
| 10 | 001010 | K | K | 0x4B |
| 11 | 001011 | L | L | 0x4C |
| 12 | 001100 | M | M | 0x4D |
| 13 | 001101 | N | N | 0x4E |
| 14 | 001110 | O | O | 0x4F |
| 15 | 001111 | P | P | 0x50 |
| 16 | 010000 | Q | Q | 0x51 |
| 17 | 010001 | R | R | 0x52 |
| 18 | 010010 | S | S | 0x53 |
| 19 | 010011 | T | T | 0x54 |
| 20 | 010100 | U | U | 0x55 |
| 21 | 010101 | V | V | 0x56 |
| 22 | 010110 | W | W | 0x57 |
| 23 | 010111 | X | X | 0x58 |
| 24 | 011000 | Y | Y | 0x59 |
| 25 | 011001 | Z | Z | 0x5A |
| 26 | 011010 | a | a | 0x61 |
| 27 | 011011 | b | b | 0x62 |
| 28 | 011100 | c | c | 0x63 |
| 29 | 011101 | d | d | 0x64 |
| 30 | 011110 | e | e | 0x65 |
| 31 | 011111 | f | f | 0x66 |
| 32 | 100000 | g | g | 0x67 |
| 33 | 100001 | h | h | 0x68 |
| 34 | 100010 | i | i | 0x69 |
| 35 | 100011 | j | j | 0x6A |
| 36 | 100100 | k | k | 0x6B |
| 37 | 100101 | l | l | 0x6C |
| 38 | 100110 | m | m | 0x6D |
| 39 | 100111 | n | n | 0x6E |
| 40 | 101000 | o | o | 0x6F |
| 41 | 101001 | p | p | 0x70 |
| 42 | 101010 | q | q | 0x71 |
| 43 | 101011 | r | r | 0x72 |
| 44 | 101100 | s | s | 0x73 |
| 45 | 101101 | t | t | 0x74 |
| 46 | 101110 | u | u | 0x75 |
| 47 | 101111 | v | v | 0x76 |
| 48 | 110000 | w | w | 0x77 |
| 49 | 110001 | x | x | 0x78 |
| 50 | 110010 | y | y | 0x79 |
| 51 | 110011 | z | z | 0x7A |
| 52 | 110100 | 0 | 0 | 0x30 |
| 53 | 110101 | 1 | 1 | 0x31 |
| 54 | 110110 | 2 | 2 | 0x32 |
| 55 | 110111 | 3 | 3 | 0x33 |
| 56 | 111000 | 4 | 4 | 0x34 |
| 57 | 111001 | 5 | 5 | 0x35 |
| 58 | 111010 | 6 | 6 | 0x36 |
| 59 | 111011 | 7 | 7 | 0x37 |
| 60 | 111100 | 8 | 8 | 0x38 |
| 61 | 111101 | 9 | 9 | 0x39 |
| 62 | 111110 | + | - | 0x2B |
| 63 | 111111 | / | _ | 0x2F |
| preenchimento | – | = | geralmente omitido | 0x3D |
Vale a pena decorar duas faixas. Todo caractere de A a P (0 a 15) começa com os bits 00, e todo caractere de w a / (48 a 63) começa com 11. Isso basta para decodificar um caractere de cabeça quando você confere um prefixo à mão. Um exemplo completo da divisão em bits está em como o Base64 funciona.
A ordem do alfabeto não é a ordem ASCII. No ASCII, + e / vêm primeiro, depois os dígitos, depois as maiúsculas e por último as minúsculas. Por isso, ordenar strings Base64 não ordena os bytes por trás delas: +A== (o byte F8) fica antes de AA== (o byte 00). Se você precisa de valores codificados que se ordenem como os bytes brutos, use o base32hex da RFC 4648 ou hex simples.
O alfabeto URL-safe
+ e / têm significado especial em URLs. + é decodificado como espaço em query strings e dados de formulário, e / separa os segmentos do caminho. O Base64URL, definido na seção 5 da RFC 4648, mantém os índices de 0 a 61 e troca os dois últimos:
| Índice | Base64 | Base64URL |
|---|---|---|
| 62 | + | - |
| 63 | / | _ |
Todo o resto, inclusive a disposição dos bits, é idêntico, então converter de um para o outro é uma troca de caracteres mais a inclusão ou remoção do preenchimento. JWTs, muitos tokens de API e identificadores seguros para nomes de arquivo usam Base64URL, geralmente sem =. O codificador Base64URL gera esse formato diretamente. A comparação completa está em Base64 vs Base64URL.
O caractere de preenchimento
= (ASCII 0x3D) não faz parte do alfabeto de 64 caracteres e nunca codifica dados. Ele só completa o último grupo de 4 caracteres quando o tamanho da entrada não é múltiplo de 3:
- Sobra 1 byte: 2 caracteres de dados mais
==. - Sobram 2 bytes: 3 caracteres de dados mais
=. - Não sobra nenhum byte: sem preenchimento.
Assim, uma string com preenchimento sempre tem comprimento múltiplo de 4, e você nunca vê ===. Sem preenchimento, o comprimento dividido por 4 deixa resto 0, 2 ou 3, nunca 1. O guia de preenchimento explica quando o = pode ser omitido e como restaurá-lo.
Quais caracteres aparecem onde
Alguns padrões decorrem diretamente da disposição dos bits. Eles foram conferidos por força bruta em todos os valores de byte relevantes.
Antes de == só aparecem A, Q, g ou w. Quando sobra um byte, o segundo caractere carrega 2 bits de dados seguidos de 4 bits zero, então o índice dele é 0, 16, 32 ou 48. Antes de um único =, o terceiro caractere termina com 2 bits zero, então é um destes 16: A E I M Q U Y c g k o s w 0 4 8. Qualquer outro caractere nessa posição indica uma codificação não canônica, que decodificadores rígidos rejeitam.
Bytes aleatórios usam os 64 caracteres por igual. Cada grupo de 6 bits de dados aleatórios tem distribuição uniforme, então dados criptografados, chaves e arquivos compactados produzem uma distribuição de caracteres plana. Uma distribuição desigual é sinal de que os dados são texto ou têm estrutura.
Texto ASCII nunca começa um grupo com g a z minúsculos, dígitos, + ou /. O primeiro caractere de cada grupo de 4 guarda os 6 bits mais altos de um byte. No ASCII de 7 bits o bit mais alto é 0, então esse caractere fica sempre entre A e f (índice 0 a 31). Em SGVsbG8gd29ybGQh (Hello world!), os grupos começam com S, b, d e b.
No Base64 de texto ASCII, + e / são raros. Para bytes abaixo de 0x80, + só pode aparecer como quarto caractere de um grupo, quando o terceiro byte é > ou ~. / só aparece ali quando esse byte é ? ou o caractere de controle DEL. É por isso que Hi?> vira SGk/Pg== e <b> vira PGI+.
Sequências de A são bytes zero, sequências de / são 0xFF. AAAA são três bytes 00, //// são três bytes FF. Trechos longos de A são típicos de formatos binários esparsos, de texto UTF-16 (Hello é SABlAGwAbABvAA==) e dos campos de tamanho no início das chaves SSH. Mais padrões reconhecíveis estão em prefixos Base64 comuns.
Outros alfabetos Base64
Vários sistemas mantiveram a ideia de 64 caracteres para 6 bits, mas escolheram caracteres diferentes:
| Variante | Alfabeto na ordem dos índices | Onde |
|---|---|---|
| Padrão | A-Z a-z 0-9 + / | RFC 4648, MIME, PEM, a maioria das APIs |
| URL-safe | A-Z a-z 0-9 - _ | RFC 4648 seção 5, JWT |
| Nomes de caixas de correio IMAP | A-Z a-z 0-9 + , | UTF-7 modificado da RFC 3501 |
| bcrypt | . / A-Z a-z 0-9 | Hashes de senha $2a$, $2b$, $2y$ |
| crypt(3) | . / 0-9 A-Z a-z | MD5-crypt $1$, SHA-crypt $5$ e $6$, DES crypt |
| xxencode | + - 0-9 A-Z a-z | E-mail antigo do Unix e Usenet |
| uuencode | ASCII 32 a 95 (do espaço a _), muitas vezes com ` para 0 | E-mail antigo do Unix e Usenet |
- IMAP troca
/por,porque/é um separador de hierarquia comum em nomes de caixas de correio. Uma pasta chamadaEntwürfeé armazenada comoEntw&APw-rfe. - bcrypt passa
.e/para o início e mantém as letras antes dos dígitos. Os salts e hashes dele são Base64 nesse alfabeto, sem preenchimento, e é por isso que um decodificador padrão devolve os bytes errados. - crypt(3) usa
./0-9A-Za-z, que é a ordem ASCII. Ele também empacota os bits a partir do lado menos significativo, então mesmo com o alfabeto traduzido um decodificador padrão não reproduz os bytes do hash. - uuencode e xxencode são anteriores ao MIME. As ferramentas uuencode e xxencode leem e escrevem os dois formatos.
Para codificações com alfabetos de outros tamanhos, como Base32, Base58 e Base85, veja Base64 vs hex, Base32, Base58 e Base85. As definições dos termos usados aqui estão no glossário.
Perguntas frequentes
Quantos caracteres tem o alfabeto Base64?
64 caracteres para os dados: 26 letras maiúsculas, 26 minúsculas, 10 dígitos, + e /. O sinal de preenchimento = é um 65º símbolo que nunca carrega dados.
Qual é o valor da letra A no Base64?
A corresponde ao índice 0, binário 000000. B é 1, Z é 25, a é 26, z é 51, 0 é 52, 9 é 61, + é 62 e / é 63.
Quais caracteres o Base64URL troca?
Só dois: + (índice 62) vira - e / (índice 63) vira _. O preenchimento também costuma ser removido. Converta com Base64 para Base64URL.