Whiz Tools

Codificador/Decodificador Base64

Converteix text a i des de la codificació Base64

Copia

Codificador i Decodificador Base64

Introducció

Base64 és un esquema de codificació de text a binari que representa dades binàries en un format de cadena ASCII. Està dissenyat per transportar dades emmagatzemades en formats binaris a través de canals que només suporten de manera fiable contingut de text. La codificació Base64 converteix dades binàries en un conjunt de 64 caràcters (d'aquí el nom) que poden ser transmesos de manera segura a través de protocols basats en text sense corrupció de dades.

El conjunt de caràcters Base64 consisteix en:

  • Lletres majúscules A-Z (26 caràcters)
  • Lletres minúscules a-z (26 caràcters)
  • Dits 0-9 (10 caràcters)
  • Dos caràcters addicionals, típicament "+" i "/" (2 caràcters)

Aquest eina et permet codificar fàcilment text al format Base64 o decodificar cadenes Base64 de nou al seu text original. És particularment útil per a desenvolupadors, professionals d'IT i qualsevol persona que treballi amb dades que necessiten ser transmeses de manera segura a través de canals basats en text.

Com Funciona la Codificació Base64

Procés de Codificació

La codificació Base64 funciona convertint cada grup de tres bytes (24 bits) de dades binàries en quatre caràcters Base64. El procés segueix aquests passos:

  1. Converteix el text d'entrada a la seva representació binària (utilitzant codificació ASCII o UTF-8)
  2. Agrupa les dades binàries en trossos de 24 bits (3 bytes)
  3. Divideix cada tros de 24 bits en quatre grups de 6 bits
  4. Converteix cada grup de 6 bits al seu caràcter Base64 corresponent

Quan la longitud de l'entrada no és divisible per 3, s'afegeix un ompliment amb caràcters "=" per mantenir la proporció de 4:3 de longituds de sortida a entrada.

Representació Matemàtica

Per a una seqüència de bytes b1,b2,b3b_1, b_2, b_3, els caràcters Base64 corresponents c1,c2,c3,c4c_1, c_2, c_3, c_4 es calculen com:

c1=Base64[(b1>>2)]c_1 = \text{Base64}[(b_1 >> 2)]
c2=Base64[((b1&3)<<4)(b2>>4)]c_2 = \text{Base64}[((b_1 \& 3) << 4) | (b_2 >> 4)]
c3=Base64[((b2&15)<<2)(b3>>6)]c_3 = \text{Base64}[((b_2 \& 15) << 2) | (b_3 >> 6)]
c4=Base64[(b3&63)]c_4 = \text{Base64}[(b_3 \& 63)]

On Base64[i]\text{Base64}[i] representa el ii-è caracter de l'alfabet Base64.

Procés de Decodificació

La decodificació Base64 inverteix el procés de codificació:

  1. Converteix cada caràcter Base64 al seu valor de 6 bits
  2. Concatena aquests valors de 6 bits
  3. Agrupa els bits en trossos de 8 bits (bytes)
  4. Converteix cada byte al seu caràcter corresponent

Ompliment

Quan el nombre de bytes a codificar no és divisible per 3, s'aplica un ompliment:

  • Si queda un byte, es converteix en dos caràcters Base64 seguits de "=="
  • Si queden dos bytes, es converteixen en tres caràcters Base64 seguits de "="

Exemple

Vegem com codificar el text "Hello" a Base64:

  1. Representació ASCII de "Hello": 72 101 108 108 111
  2. Representació binària: 01001000 01100101 01101100 01101100 01101111
  3. Agrupament en trossos de 6 bits: 010010 000110 010101 101100 011011 000110 1111
  4. L'últim tros només té 4 bits, així que omplim amb zeros: 010010 000110 010101 101100 011011 000110 111100
  5. Convertint a decimal: 18, 6, 21, 44, 27, 6, 60
  6. Buscant a l'alfabet Base64: S, G, V, s, b, G, 8
  7. El resultat és "SGVsbG8="

Nota l'ompliment "=" al final perquè la longitud de l'entrada (5 bytes) no és divisible per 3.

Fórmula

La fórmula general per calcular la longitud d'una cadena codificada en Base64 és:

longitud_codificada=4×longitud_entrada3\text{longitud\_codificada} = 4 \times \lceil \frac{\text{longitud\_entrada}}{3} \rceil

On x\lceil x \rceil representa la funció sostre (arrodonint cap amunt al nombre enter més proper).

Casos d'Ús

La codificació Base64 s'utilitza àmpliament en diverses aplicacions:

  1. Arxius Adjunts d'Email: MIME (Extensions de Correu Internet Multimèdia) utilitza Base64 per codificar arxius adjunts binaris en correus electrònics.

  2. URLs de Dades: Incorporar imatges petites, fonts o altres recursos directament en HTML, CSS o JavaScript mitjançant l'esquema d'URL data:.

  3. Comunicacions API: Transmetre de manera segura dades binàries en càrregues útils JSON o altres formats d'API basats en text.

  4. Emmagatzematge de Dades Binàries en Formats de Text: Quan les dades binàries necessiten ser emmagatzemades en XML, JSON o altres formats basats en text.

  5. Sistemes d'Autenticació: L'Autenticació Bàsica en HTTP utilitza la codificació Base64 (encara que no és per seguretat, només per codificació).

  6. Criptografia: Com a part de diversos protocols i sistemes criptogràfics, sovint per codificar claus o certificats.

  7. Valors de Cookies: Codificant estructures de dades complexes per ser emmagatzemades en cookies.

Alternatives

Si bé Base64 és àmpliament utilitzat, hi ha alternatives que podrien ser més apropiades en certes situacions:

  1. Base64 Segur per a URL: Una variant que utilitza "-" i "_" en lloc de "+" i "/" per evitar problemes de codificació d'URL. Útil per a dades que s'inclouran en URLs.

  2. Base32: Utilitza un conjunt de 32 caràcters, resultant en una sortida més llarga però amb millor llegibilitat humana i insensibilitat a majúscules.

  3. Codificació Hexadecimal: Conversió simple a hexadecimal, que és menys eficient (duplica la mida) però molt simple i àmpliament suportada.

  4. Transferència Binària: Per a fitxers grans o quan l'eficiència és crucial, els protocols de transferència binària directa com HTTP amb els encapçalaments de tipus de contingut apropiats són preferibles.

  5. Compressió + Base64: Per a grans dades de text, comprimir abans de codificar pot mitigar l'augment de mida.

  6. Serialització JSON/XML: Per a dades estructurades, utilitzar la serialització nativa JSON o XML podria ser més apropiat que la codificació Base64.

Història

La codificació Base64 té les seves arrels en els primers sistemes informàtics i de telecomunicacions on les dades binàries necessitaven ser transmeses a través de canals dissenyats per al text.

La especificació formal de Base64 es va publicar per primera vegada el 1987 com a part de l'RFC 989, que definia el Correu Privat Millorat (PEM). Això es va actualitzar més tard en l'RFC 1421 (1993) i l'RFC 2045 (1996, com a part de MIME).

El terme "Base64" prové del fet que la codificació utilitza 64 caràcters ASCII diferents per representar dades binàries. Aquesta elecció de 64 caràcters va ser deliberada, ja que 64 és una potència de 2 (2^6), cosa que fa que la conversió entre binari i Base64 sigui eficient.

Amb el temps, han emergit diverses variants de Base64:

  • Base64 Estàndard: Tal com es defineix a l'RFC 4648, utilitzant A-Z, a-z, 0-9, +, / i = per a l'ompliment
  • Base64 Segur per a URL: Utilitza - i _ en lloc de + i / per evitar problemes de codificació d'URL
  • Base64 Segur per a Noms de Fitxers: Similar al segur per a URL, dissenyat per a l'ús en noms de fitxers
  • Base64 Modificat per IMAP: Utilitzat en el protocol IMAP amb un conjunt diferent de caràcters especials

Malgrat tenir més de tres dècades, Base64 continua sent una eina fonamental en la informàtica moderna, particularment amb l'augment d'aplicacions web i APIs que depenen fortament de formats de dades basats en text com JSON.

Exemple de Codi

Aquí hi ha exemples de codificació i decodificació Base64 en diversos llenguatges de programació:

// JavaScript Codificació/Decodificació Base64
function encodeToBase64(text) {
  return btoa(text);
}

function decodeFromBase64(base64String) {
  try {
    return atob(base64String);
  } catch (e) {
    throw new Error("Cadena Base64 no vàlida");
  }
}

// Exemple d'ús
const originalText = "Hello, World!";
const encoded = encodeToBase64(originalText);
console.log("Codificat:", encoded);  // SGVsbG8sIFdvcmxkIQ==

try {
  const decoded = decodeFromBase64(encoded);
  console.log("Decodificat:", decoded);  // Hello, World!
} catch (error) {
  console.error(error.message);
}
# Python Codificació/Decodificació Base64
import base64

def encode_to_base64(text):
    # Convertir cadena a bytes i després codificar
    text_bytes = text.encode('utf-8')
    base64_bytes = base64.b64encode(text_bytes)
    return base64_bytes.decode('utf-8')

def decode_from_base64(base64_string):
    try:
        # Convertir cadena base64 a bytes i després decodificar
        base64_bytes = base64_string.encode('utf-8')
        text_bytes = base64.b64decode(base64_bytes)
        return text_bytes.decode('utf-8')
    except Exception as e:
        raise ValueError(f"Cadena Base64 no vàlida: {e}")

# Exemple d'ús
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
print(f"Codificat: {encoded}")  # SGVsbG8sIFdvcmxkIQ==

try:
    decoded = decode_from_base64(encoded)
    print(f"Decodificat: {decoded}")  # Hello, World!
except ValueError as e:
    print(e)
// Java Codificació/Decodificació Base64
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class Base64Example {
    public static String encodeToBase64(String text) {
        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
        byte[] encodedBytes = Base64.getEncoder().encode(textBytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }
    
    public static String decodeFromBase64(String base64String) {
        try {
            byte[] base64Bytes = base64String.getBytes(StandardCharsets.UTF_8);
            byte[] decodedBytes = Base64.getDecoder().decode(base64Bytes);
            return new String(decodedBytes, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Cadena Base64 no vàlida: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        String originalText = "Hello, World!";
        String encoded = encodeToBase64(originalText);
        System.out.println("Codificat: " + encoded);  // SGVsbG8sIFdvcmxkIQ==
        
        try {
            String decoded = decodeFromBase64(encoded);
            System.out.println("Decodificat: " + decoded);  // Hello, World!
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        }
    }
}
<?php
// PHP Codificació/Decodificació Base64
function encodeToBase64($text) {
    return base64_encode($text);
}

function decodeFromBase64($base64String) {
    $decoded = base64_decode($base64String, true);
    if ($decoded === false) {
        throw new Exception("Cadena Base64 no vàlida");
    }
    return $decoded;
}

// Exemple d'ús
$originalText = "Hello, World!";
$encoded = encodeToBase64($originalText);
echo "Codificat: " . $encoded . "\n";  // SGVsbG8sIFdvcmxkIQ==

try {
    $decoded = decodeFromBase64($encoded);
    echo "Decodificat: " . $decoded . "\n";  // Hello, World!
} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}
?>
// C# Codificació/Decodificació Base64
using System;
using System.Text;

class Base64Example
{
    public static string EncodeToBase64(string text)
    {
        byte[] textBytes = Encoding.UTF8.GetBytes(text);
        return Convert.ToBase64String(textBytes);
    }
    
    public static string DecodeFromBase64(string base64String)
    {
        try
        {
            byte[] base64Bytes = Convert.FromBase64String(base64String);
            return Encoding.UTF8.GetString(base64Bytes);
        }
        catch (FormatException)
        {
            throw new FormatException("Cadena Base64 no vàlida");
        }
    }
    
    static void Main()
    {
        string originalText = "Hello, World!";
        string encoded = EncodeToBase64(originalText);
        Console.WriteLine($"Codificat: {encoded}");  // SGVsbG8sIFdvcmxkIQ==
        
        try
        {
            string decoded = DecodeFromBase64(encoded);
            Console.WriteLine($"Decodificat: {decoded}");  // Hello, World!
        }
        catch (FormatException e)
        {
            Console.WriteLine($"Error: {e.Message}");
        }
    }
}
# Ruby Codificació/Decodificació Base64
require 'base64'

def encode_to_base64(text)
  Base64.strict_encode64(text)
end

def decode_from_base64(base64_string)
  begin
    Base64.strict_decode64(base64_string)
  rescue ArgumentError => e
    raise "Cadena Base64 no vàlida: #{e.message}"
  end
end

# Exemple d'ús
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
puts "Codificat: #{encoded}"  # SGVsbG8sIFdvcmxkIQ==

begin
  decoded = decode_from_base64(encoded)
  puts "Decodificat: #{decoded}"  # Hello, World!
rescue StandardError => e
  puts "Error: #{e.message}"
end
// Go Codificació/Decodificació Base64
package main

import (
    "encoding/base64"
    "fmt"
)

func encodeToBase64(text string) string {
    return base64.StdEncoding.EncodeToString([]byte(text))
}

func decodeFromBase64(base64String string) (string, error) {
    bytes, err := base64.StdEncoding.DecodeString(base64String)
    if err != nil {
        return "", fmt.Errorf("cadena Base64 no vàlida: %v", err)
    }
    return string(bytes), nil
}

func main() {
    originalText := "Hello, World!"
    encoded := encodeToBase64(originalText)
    fmt.Println("Codificat:", encoded)  // SGVsbG8sIFdvcmxkIQ==
    
    decoded, err := decodeFromBase64(encoded)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Decodificat:", decoded)  // Hello, World!
    }
}
// Swift Codificació/Decodificació Base64
import Foundation

func encodeToBase64(_ text: String) -> String? {
    if let data = text.data(using: .utf8) {
        return data.base64EncodedString()
    }
    return nil
}

func decodeFromBase64(_ base64String: String) -> String? {
    if let data = Data(base64Encoded: base64String) {
        return String(data: data, encoding: .utf8)
    }
    return nil
}

// Exemple d'ús
let originalText = "Hello, World!"
if let encoded = encodeToBase64(originalText) {
    print("Codificat: \(encoded)")  // SGVsbG8sIFdvcmxkIQ==
    
    if let decoded = decodeFromBase64(encoded) {
        print("Decodificat: \(decoded)")  // Hello, World!
    } else {
        print("Error: No es pot decodificar la cadena Base64")
    }
} else {
    print("Error: No es pot codificar el text")
}
' Excel VBA Codificació/Decodificació Base64
' Nota: Això requereix una referència a Microsoft XML, v6.0
Function EncodeToBase64(text As String) As String
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.nodeTypedValue = StrConv(text, vbFromUnicode)
    
    EncodeToBase64 = xmlNode.text
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
End Function

Function DecodeFromBase64(base64String As String) As String
    On Error GoTo ErrorHandler
    
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.text = base64String
    
    DecodeFromBase64 = StrConv(xmlNode.nodeTypedValue, vbUnicode)
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
    Exit Function
    
ErrorHandler:
    DecodeFromBase64 = "Error: Cadena Base64 no vàlida"
End Function

' Ús en una fulla de càlcul:
' =EncodeToBase64("Hello, World!")
' =DecodeFromBase64("SGVsbG8sIFdvcmxkIQ==")
# R Codificació/Decodificació Base64
# Requereix el paquet 'base64enc'
# install.packages("base64enc")
library(base64enc)

encode_to_base64 <- function(text) {
  # Convertir text a bytes crues, després codificar
  text_raw <- charToRaw(text)
  base64_encoded <- base64encode(text_raw)
  return(rawToChar(base64_encoded))
}

decode_from_base64 <- function(base64_string) {
  tryCatch({
    # Convertir cadena base64 a bytes crues, després decodificar
    base64_raw <- charToRaw(base64_string)
    decoded_raw <- base64decode(base64_raw)
    return(rawToChar(decoded_raw))
  }, error = function(e) {
    stop(paste("Cadena Base64 no vàlida:", e$message))
  })
}

# Exemple d'ús
original_text <- "Hello, World!"
encoded <- encode_to_base64(original_text)
cat("Codificat:", encoded, "\n")  # SGVsbG8sIFdvcmxkIQ==

tryCatch({
  decoded <- decode_from_base64(encoded)
  cat("Decodificat:", decoded, "\n")  # Hello, World!
}, error = function(e) {
  cat("Error:", e$message, "\n")
})
% MATLAB Codificació/Decodificació Base64
function demo_base64()
    originalText = 'Hello, World!';
    
    % Codificar
    encoded = encode_to_base64(originalText);
    fprintf('Codificat: %s\n', encoded);  % SGVsbG8sIFdvcmxkIQ==
    
    % Decodificar
    try
        decoded = decode_from_base64(encoded);
        fprintf('Decodificat: %s\n', decoded);  % Hello, World!
    catch e
        fprintf('Error: %s\n', e.message);
    end
end

function encoded = encode_to_base64(text)
    % Convertir text a uint8 array i codificar
    bytes = uint8(text);
    encoded = base64encode(bytes);
end

function decoded = decode_from_base64(base64String)
    try
        % Decodificar cadena base64 a uint8 array
        bytes = base64decode(base64String);
        decoded = char(bytes);
    catch
        error('Cadena Base64 no vàlida');
    end
end
// C Codificació/Decodificació Base64 utilitzant OpenSSL
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <stdint.h>

char* encode_to_base64(const char* input) {
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    BIO_write(bio, input, strlen(input));
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    
    char* result = (char*)malloc(bufferPtr->length + 1);
    memcpy(result, bufferPtr->data, bufferPtr->length);
    result[bufferPtr->length] = '\0';
    
    BIO_free_all(bio);
    
    return result;
}

char* decode_from_base64(const char* input) {
    BIO *bio, *b64;
    size_t length = strlen(input);
    char* buffer = (char*)malloc(length);
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new_mem_buf(input, -1);
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    int decoded_length = BIO_read(bio, buffer, length);
    
    if (decoded_length <= 0) {
        free(buffer);
        BIO_free_all(bio);
        return NULL; // Entrada Base64 no vàlida
    }
    
    buffer[decoded_length] = '\0';
    
    BIO_free_all(bio);
    
    return buffer;
}

int main() {
    const char* original_text = "Hello, World!";
    
    char* encoded = encode_to_base64(original_text);
    printf("Codificat: %s\n", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    char* decoded = decode_from_base64(encoded);
    if (decoded) {
        printf("Decodificat: %s\n", decoded);  // Hello, World!
        free(decoded);
    } else {
        printf("Error: Cadena Base64 no vàlida\n");
    }
    
    free(encoded);
    
    return 0;
}
// Rust Codificació/Decodificació Base64
use base64::{encode, decode};
use std::str;

fn encode_to_base64(text: &str) -> String {
    encode(text)
}

fn decode_from_base64(base64_string: &str) -> Result<String, String> {
    match decode(base64_string) {
        Ok(bytes) => {
            match str::from_utf8(&bytes) {
                Ok(text) => Ok(text.to_string()),
                Err(e) => Err(format!("Seqüència UTF-8 no vàlida: {}", e))
            }
        },
        Err(e) => Err(format!("Cadena Base64 no vàlida: {}", e))
    }
}

fn main() {
    let original_text = "Hello, World!";
    let encoded = encode_to_base64(original_text);
    println!("Codificat: {}", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    match decode_from_base64(&encoded) {
        Ok(decoded) => println!("Decodificat: {}", decoded),  // Hello, World!
        Err(e) => println!("Error: {}", e)
    }
}

Casos Extrems i Consideracions

En treballar amb codificació i decodificació Base64, tingues en compte aquestes consideracions importants:

  1. Unicode i Caràcters No ASCII: Quan codifiques text amb caràcters no ASCII, assegura't d'utilitzar la codificació de caràcters adequada (normalment UTF-8) abans de la codificació Base64.

  2. Ompliment: La Base64 estàndard utilitza ompliment amb caràcters "=" per assegurar que la longitud de sortida sigui un múltiple de 4. Algunes implementacions permeten ometre l'ompliment, cosa que pot causar problemes de compatibilitat.

  3. Salt de Línia: Les implementacions tradicionals de Base64 inserten salts de línia (típicament cada 76 caràcters) per llegibilitat, però les aplicacions modernes sovint els ometen.

  4. Base64 Segur per a URL: La Base64 estàndard utilitza "+" i "/" que tenen significats especials en URLs. Per a contextos d'URL, utilitza Base64 segur per a URLs que substitueix aquests per "-" i "_".

  5. Espai en Blanc: En decodificar, algunes implementacions són indulgents i ignoren espais en blanc, mentre que altres requereixen una entrada exacta.

  6. Augment de Mida: La codificació Base64 augmenta la mida de les dades aproximadament un 33% (4 bytes de sortida per cada 3 bytes d'entrada).

  7. Rendiment: La codificació/decodificació Base64 pot ser intensiva en computació per a dades molt grans. Considera enfocaments de flux per a fitxers grans.

Referències

  1. RFC 4648 - Les Codificacions de Dades Base16, Base32 i Base64
  2. RFC 2045 - MIME Part One: Format de Cossos de Missatge d'Internet
  3. MDN Web Docs: Codificació i Decodificació Base64
  4. Base64 - Viquipèdia
  5. MIME - Viquipèdia
Feedback