Toolypet
Volver al Blog
Dev

Todo Sobre Codificacion Base64 - De Principios a Aplicaciones Practicas

Aprende todo sobre codificacion Base64: que es, por que se necesita y como usarla con ejemplos practicos. Desde imagenes inline hasta JWT.

Toolypet Team

Toolypet Team

Development Team

8 min de lectura

Todo Sobre Codificacion Base64

"Como envio esta imagen via API?" "Como pongo estos datos binarios en JSON?"

La respuesta es Base64.

Esta guia cubre todo desde los principios de Base64 hasta aplicaciones practicas.


Que es Base64?

Base64 es un metodo de codificacion que convierte datos binarios a texto.

Por que se necesita?

ProblemaSolucion Base64
No se puede enviar binario por emailConvertir a texto para transmision
No se puede incluir binario en JSONConvertir a string para inclusion
Caracteres especiales no permitidos en URLUsar solo caracteres seguros para URL
Insertar imagenes inline en HTMLConvertir a Data URL

Caracteristicas

  • 64 caracteres usados: A-Z, a-z, 0-9, +, / (estandar)
  • Aumento de tamano: Aproximadamente 33% mas grande que el original
  • Reversible: Codificacion <-> decodificacion con restauracion perfecta
  • No es encriptacion: Cualquiera puede decodificar

Como Funciona Base64

Proceso de Codificacion

Cadena original: "Man"

1. Conversion ASCII
   M = 77 = 01001101
   a = 97 = 01100001
   n = 110 = 01101110

2. Dividir en chunks de 6 bits
   010011 | 010110 | 000101 | 101110
      19  |   22   |    5   |   46

3. Convertir a caracteres Base64 (A=0, B=1, ... Z=25, a=26, ...)
   19 = T
   22 = W
   5  = F
   46 = u

Resultado: "TWFu"

Tabla de Caracteres Base64

Indice: Caracter
0-25:   A-Z
26-51:  a-z
52-61:  0-9
62:     +
63:     /
Relleno:   =

Relleno (=)

Si la longitud original no es divisible por 3, agregar relleno

"M"   -> "TQ=="  (2 rellenos)
"Ma"  -> "TWE="  (1 relleno)
"Man" -> "TWFu"  (sin relleno)

Implementacion por Lenguaje

JavaScript (Navegador)

// Codificacion
const encoded = btoa('Hello, World!');
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="

// Decodificacion
const decoded = atob('SGVsbG8sIFdvcmxkIQ==');
console.log(decoded); // "Hello, World!"

// Manejo de Unicode (caracteres no-ASCII)
function encodeUnicode(str) {
  return btoa(encodeURIComponent(str).replace(
    /%([0-9A-F]{2})/g,
    (_, p1) => String.fromCharCode(parseInt(p1, 16))
  ));
}

function decodeUnicode(str) {
  return decodeURIComponent(
    Array.from(atob(str), c =>
      '%' + c.charCodeAt(0).toString(16).padStart(2, '0')
    ).join('')
  );
}

// Prueba Unicode
const text = 'Hola Mundo';
const encodedText = encodeUnicode(text);
console.log(encodedText);
console.log(decodeUnicode(encodedText)); // "Hola Mundo"

Node.js

// Usando Buffer
const encoded = Buffer.from('Hello, World!').toString('base64');
console.log(encoded); // "SGVsbG8sIFdvcmxkIQ=="

const decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64').toString('utf-8');
console.log(decoded); // "Hello, World!"

// Codificacion de archivo
const fs = require('fs');

const imageBuffer = fs.readFileSync('image.png');
const base64Image = imageBuffer.toString('base64');
console.log(base64Image.substring(0, 50) + '...');

Python

import base64

# Codificacion
encoded = base64.b64encode(b'Hello, World!').decode('utf-8')
print(encoded)  # "SGVsbG8sIFdvcmxkIQ=="

# Decodificacion
decoded = base64.b64decode('SGVsbG8sIFdvcmxkIQ==').decode('utf-8')
print(decoded)  # "Hello, World!"

# Unicode
text = 'Hola Mundo'
encoded_text = base64.b64encode(text.encode('utf-8')).decode('utf-8')
print(encoded_text)

# Codificacion de archivo
with open('image.png', 'rb') as f:
    base64_image = base64.b64encode(f.read()).decode('utf-8')

Go

package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    // Codificacion
    data := "Hello, World!"
    encoded := base64.StdEncoding.EncodeToString([]byte(data))
    fmt.Println(encoded) // "SGVsbG8sIFdvcmxkIQ=="

    // Decodificacion
    decoded, _ := base64.StdEncoding.DecodeString(encoded)
    fmt.Println(string(decoded)) // "Hello, World!"

    // Base64 seguro para URL
    urlSafe := base64.URLEncoding.EncodeToString([]byte(data))
    fmt.Println(urlSafe)
}

Aplicaciones Practicas

1. Insercion de Imagen Inline (Data URL)

<!-- Insertar imagen directamente en HTML -->
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" alt="1x1 red pixel">
// Archivo -> Base64 Data URL
function fileToDataUrl(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

// Uso
const file = document.getElementById('fileInput').files[0];
const dataUrl = await fileToDataUrl(file);
document.getElementById('preview').src = dataUrl;

2. Enviar Imagenes via API

// Cliente
async function uploadImage(file) {
  const base64 = await fileToBase64(file);

  const response = await fetch('/api/upload', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      filename: file.name,
      contentType: file.type,
      data: base64,
    }),
  });

  return response.json();
}

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      // Eliminar prefijo data:image/png;base64,
      const base64 = reader.result.split(',')[1];
      resolve(base64);
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}
// Servidor (Node.js)
app.post('/api/upload', (req, res) => {
  const { filename, contentType, data } = req.body;

  // Base64 -> Buffer -> Guardar archivo
  const buffer = Buffer.from(data, 'base64');
  fs.writeFileSync(`uploads/${filename}`, buffer);

  res.json({ success: true, filename });
});

3. Tokens JWT

// JWT = Header.Payload.Signature (cada uno codificado en Base64URL)

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';

// Decodificar Payload
const payload = token.split('.')[1];
const decoded = JSON.parse(atob(payload));
console.log(decoded);
// { sub: "1234567890", name: "John Doe", iat: 1516239022 }

4. Autenticacion Basic

// HTTP Basic Authentication
const username = 'user';
const password = 'password';

const credentials = btoa(`${username}:${password}`);

fetch('/api/protected', {
  headers: {
    'Authorization': `Basic ${credentials}`,
  },
});

// Header: Authorization: Basic dXNlcjpwYXNzd29yZA==

5. Adjuntos de Email (MIME)

Content-Type: application/pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="document.pdf"

JVBERi0xLjQKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIK
Pj4KZW5kb2JqCjIgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0K
...

Variantes de Base64

Base64 Seguro para URL

EstandarSeguro para URL
+-
/_
=Puede omitirse
// Codificacion segura para URL
function toUrlSafeBase64(str) {
  return btoa(str)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

// Decodificacion segura para URL
function fromUrlSafeBase64(str) {
  // Restaurar relleno
  const pad = str.length % 4;
  const padded = pad ? str + '='.repeat(4 - pad) : str;

  return atob(
    padded
      .replace(/-/g, '+')
      .replace(/_/g, '/')
  );
}

Base64 vs Base32 vs Base16

CodificacionCaracteresAumento de TamanoCaso de Uso
Base6464+33%Proposito general
Base3232+60%Cuando se necesita insensibilidad a mayusculas
Base16 (Hex)16+100%Hashes, codigos de color

Precauciones

1. No es Encriptacion

// NO usar para seguridad
const password = btoa('mySecretPassword');
// Cualquiera puede restaurar con atob()!

// Encriptar primero, luego Base64 si es necesario
const encrypted = await encryptAES(data, key);
const encoded = btoa(encrypted);

2. Aumento de Tamano

// Original: imagen de 1MB
// Base64: ~1.33MB (aumento del 33%)

// Para archivos grandes, carga directa es mas eficiente
// Usar FormData + multipart/form-data

3. Manejo de Unicode

// btoa() del navegador solo soporta Latin-1
btoa('Caracteres especiales'); // Funciona
// Non-ASCII necesita manejo especial

// Manejo de Unicode requerido
function encodeUnicode(str) {
  return btoa(unescape(encodeURIComponent(str)));
}

4. Saltos de Linea

// Algunos sistemas agregan saltos de linea cada 76 caracteres
// Estandar MIME: saltos de linea cada 76 caracteres

// Eliminar saltos de linea
const cleaned = base64String.replace(/[\r\n]/g, '');

Optimizacion de Rendimiento

Codificacion por Streaming

// Procesar archivos grandes en chunks
async function* encodeFileInChunks(file, chunkSize = 1024 * 1024) {
  const reader = file.stream().getReader();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    // Codificar cada chunk en Base64
    yield Buffer.from(value).toString('base64');
  }
}

Uso de Web Worker

// worker.js
self.onmessage = function(e) {
  const { action, data } = e.data;

  if (action === 'encode') {
    const result = btoa(data);
    self.postMessage({ result });
  }
};

// main.js
const worker = new Worker('worker.js');
worker.postMessage({ action: 'encode', data: largeString });
worker.onmessage = (e) => console.log(e.data.result);

Herramientas de Depuracion

Base64 Encoder/Decoder

  1. Ingresar texto o archivo
  2. Hacer clic en boton codificar/decodificar
  3. Copiar resultado

CLI

# Codificacion
echo -n "Hello, World!" | base64
# SGVsbG8sIFdvcmxkIQ==

# Decodificacion
echo "SGVsbG8sIFdvcmxkIQ==" | base64 -d
# Hello, World!

# Codificacion de archivo
base64 image.png > image.txt

# Decodificacion de archivo
base64 -d image.txt > restored.png

Preguntas Frecuentes

Q1: Por que Base64 aumenta el tamano en 33%?

R: Porque 3 bytes (24 bits) se representan como 4 caracteres (4x6=24 bits).

  • 3 bytes -> 4 caracteres
  • Aumento: (4-3)/3 = 33%

Q2: Por que se necesita el relleno (=)?

R: El decodificador lo necesita para saber la longitud original. El numero de caracteres de relleno indica el numero de bytes en el ultimo grupo.

Q3: Cuando deberia usar Base64URL?

R: Cuando se usa en URLs o nombres de archivo. Los caracteres + y / de Base64 estandar tienen significado especial en URLs, por eso se reemplazan con - y _.

Q4: Cuales son los pros y contras de insertar imagenes inline?

R:

  • Pros: Menos solicitudes HTTP, cache simplificado
  • Contras: Mayor tamano de HTML, sin cache individual de imagenes
  • Recomendacion: Usar solo para iconos pequenos (menos de 2KB)

Q5: Como verifico si un string es Base64 valido?

R: Usar regex para validacion de formato, luego intentar decodificar:

function isBase64(str) {
  const regex = /^[A-Za-z0-9+/]*={0,2}$/;
  if (!regex.test(str)) return false;

  try {
    atob(str);
    return true;
  } catch {
    return false;
  }
}

Conclusion

Puntos clave de Base64:

  1. Proposito: Conversion Binario -> Texto
  2. Tamano: 33% mas grande que el original
  3. Seguridad: No es encriptacion (cualquiera puede decodificar)
  4. Variantes: URL-safe usa - y _
  5. Aplicaciones: Data URL, JWT, Basic Auth, MIME

Herramientas Relacionadas

HerramientaProposito
Base64 Encoder/DecoderCodificacion/decodificacion Base64
JWT DecoderAnalisis de token JWT
JSON FormatterFormateo de JSON
Base64CodificacionDesarrolloDatosAPIJavaScript

Sobre el Autor

Toolypet Team

Toolypet Team

Development Team

The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.

Web DevelopmentCSS ToolsDeveloper ToolsSEOSecurity