Los 64 caracteres
Base64 lee la entrada de 3 en 3 bytes (24 bits) y los divide en cuatro números de 6 bits. Cada número, de 0 a 63, es un índice de esta tabla. El orden lo fija el RFC 4648: mayúsculas del 0 al 25, minúsculas del 26 al 51, dígitos del 52 al 61 y después + y /. La última columna es el código ASCII del carácter, que es lo que realmente se guarda o se envía.
| Í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 |
| relleno | – | = | suele omitirse | 0x3D |
Conviene memorizar dos rangos. Todos los caracteres de A a P (0 a 15) empiezan por los bits 00, y todos los de w a / (48 a 63) empiezan por 11. Con eso basta para decodificar un carácter de cabeza cuando revisas un prefijo a mano. En cómo funciona Base64 hay un ejemplo resuelto de la división en bits.
El orden del alfabeto no es el orden ASCII. En ASCII van primero + y /, luego los dígitos, luego las mayúsculas y por último las minúsculas. Por eso, ordenar cadenas Base64 no ordena los bytes subyacentes: +A== (el byte F8) queda antes que AA== (el byte 00). Si necesitas valores codificados que se ordenen igual que los bytes originales, usa base32hex del RFC 4648 o hexadecimal sin más.
El alfabeto URL-safe
+ y / tienen un significado especial en las URL. + se decodifica como espacio en las query strings y en los datos de formularios, y / separa los segmentos de la ruta. Base64URL, definido en la sección 5 del RFC 4648, conserva los índices 0 a 61 y cambia los dos últimos:
| Índice | Base64 | Base64URL |
|---|---|---|
| 62 | + | - |
| 63 | / | _ |
Todo lo demás, incluida la disposición de los bits, es idéntico, así que convertir de uno a otro consiste en sustituir caracteres y añadir o quitar el relleno. Los JWT, muchos tokens de API y los identificadores aptos para nombres de archivo usan Base64URL, normalmente sin =. El codificador Base64URL lo genera directamente. La comparación completa está en Base64 frente a Base64URL.
El carácter de relleno
= (ASCII 0x3D) no forma parte del alfabeto de 64 caracteres y nunca codifica datos. Solo completa el último grupo de 4 caracteres cuando la longitud de la entrada no es múltiplo de 3:
- Sobra 1 byte: 2 caracteres de datos más
==. - Sobran 2 bytes: 3 caracteres de datos más
=. - No sobra ningún byte: sin relleno.
Por tanto, una cadena con relleno siempre tiene una longitud múltiplo de 4, y nunca verás ===. Sin relleno, la longitud dividida entre 4 deja de resto 0, 2 o 3, nunca 1. La guía del relleno explica cuándo se puede omitir = y cómo restaurarlo.
Qué caracteres aparecen en cada posición
Algunos patrones se deducen directamente de la disposición de los bits. Los comprobamos por fuerza bruta con todos los valores de byte relevantes.
Antes de == solo verás A, Q, g o w. Cuando sobra un byte, el segundo carácter lleva 2 bits de datos seguidos de 4 bits a cero, así que su índice es 0, 16, 32 o 48. Antes de un solo =, el tercer carácter termina en 2 bits a cero, de modo que es uno de estos 16: A E I M Q U Y c g k o s w 0 4 8. Cualquier otro carácter en esa posición indica una codificación no canónica, que los decodificadores estrictos rechazan.
Los bytes aleatorios usan los 64 caracteres por igual. Cada grupo de 6 bits de datos aleatorios tiene una distribución uniforme, así que los datos cifrados, las claves y los archivos comprimidos producen una distribución de caracteres plana. Una distribución sesgada sugiere que los datos son texto o tienen estructura.
El texto ASCII nunca pone en primer lugar una g a z minúscula, un dígito, + ni /. El primer carácter de cada grupo de 4 contiene los 6 bits altos de un byte. En ASCII de 7 bits el bit más alto es 0, así que ese carácter siempre está entre A y f (índices 0 a 31). En SGVsbG8gd29ybGQh (Hello world!) los grupos empiezan por S, b, d y b.
En el Base64 de un texto ASCII, + y / son poco frecuentes. Con bytes por debajo de 0x80, + solo puede aparecer como cuarto carácter de un grupo, cuando el tercer byte es > o ~. / solo puede aparecer ahí cuando ese byte es ? o el carácter de control DEL. Por eso Hi?> se codifica como SGk/Pg== y <b> como PGI+.
Las rachas de A son bytes cero; las de /, bytes 0xFF. AAAA son tres bytes 00 y //// son tres bytes FF. Los tramos largos de A son típicos de formatos binarios dispersos, del texto UTF-16 (Hello es SABlAGwAbABvAA==) y de los campos de longitud al principio de las claves SSH. Encontrarás más patrones reconocibles en prefijos Base64 habituales.
Otros alfabetos Base64
Varios sistemas mantuvieron la idea de 64 caracteres por cada 6 bits, pero eligieron otros caracteres:
| Variante | Alfabeto en orden de índice | Dónde se usa |
|---|---|---|
| Estándar | A-Z a-z 0-9 + / | RFC 4648, MIME, PEM, la mayoría de las API |
| URL-safe | A-Z a-z 0-9 - _ | RFC 4648 sección 5, JWT |
| Nombres de buzón IMAP | A-Z a-z 0-9 + , | UTF-7 modificado del RFC 3501 |
| bcrypt | . / A-Z a-z 0-9 | Hashes de contraseñas $2a$, $2b$, $2y$ |
| crypt(3) | . / 0-9 A-Z a-z | MD5-crypt $1$, SHA-crypt $5$ y $6$, DES crypt |
| xxencode | + - 0-9 A-Z a-z | Correo antiguo de Unix y Usenet |
| uuencode | ASCII 32 a 95 (del espacio a _), a menudo con ` para el 0 | Correo antiguo de Unix y Usenet |
- IMAP sustituye
/por,porque/es un separador de jerarquía habitual en los nombres de buzón. Una carpeta llamadaEntwürfese guarda comoEntw&APw-rfe. - bcrypt pone
.y/al principio y deja las letras antes que los dígitos. Sus salts y hashes son Base64 en este alfabeto sin relleno, y por eso un decodificador estándar devuelve bytes incorrectos con ellos. - crypt(3) usa
./0-9A-Za-z, que es el orden ASCII. Además empaqueta los bits empezando por el extremo menos significativo, así que ni siquiera traduciendo el alfabeto un decodificador estándar reproduce los bytes del hash. - uuencode y xxencode son anteriores a MIME. Las herramientas uuencode y xxencode leen y escriben ambos formatos.
Para codificaciones con alfabetos de otro tamaño, como Base32, Base58 y Base85, consulta Base64 frente a hex, Base32, Base58 y Base85. Las definiciones de los términos usados aquí están en el glosario.
Preguntas frecuentes
¿Cuántos caracteres tiene el alfabeto Base64?
64 caracteres para datos: 26 letras mayúsculas, 26 minúsculas, 10 dígitos, + y /. El signo de relleno = es un símbolo número 65 que nunca transporta datos.
¿Qué valor tiene la letra A en Base64?
A corresponde al índice 0, en binario 000000. B es 1, Z es 25, a es 26, z es 51, 0 es 52, 9 es 61, + es 62 y / es 63.
¿Qué caracteres cambia Base64URL?
Solo dos: + (índice 62) pasa a ser - y / (índice 63) pasa a ser _. Además, el relleno se suele omitir. Convierte con Base64 a Base64URL.