Probabilmente avete già visto Base64 — quelle lunghe stringhe strane come SGVsbG8gV29ybGQ=. Compaiono nelle email, nei data URI, nei payload delle API e nei JWT. Ma cos'è esattamente Base64, e quando dovreste usarlo? Facciamo chiarezza.

Cosa fa Base64 (in parole semplici)

Base64 prende qualsiasi dato — testo, immagini, file, qualunque cosa — e lo converte in una stringa usando solo 64 caratteri ASCII "sicuri": A-Z, a-z, 0-9, + e /. Il = alla fine è padding.

Perché? Perché non tutti i sistemi gestiscono dati binari grezzi. L'email è stata progettata per il testo. JSON non supporta il binario. I parametri URL non possono contenere byte arbitrari. Base64 è il ponte che trasporta dati binari attraverso canali solo testo.

Come funziona internamente

L'algoritmo è sorprendentemente semplice. Prende 3 byte di input (24 bit), li divide in 4 gruppi da 6 bit ciascuno, e mappa ogni gruppo a uno dei 64 caratteri. Ecco un esempio rapido:

Input: Hi (2 byte: 72, 105)

Binario: 01001000 01101001 + zeri di padding

Diviso in gruppi da 6 bit: 010010 000110 100100

Mappato all'alfabeto Base64: SGk=

La matematica fa sì che l'output Base64 sia sempre circa il 33% più grande dell'input. Questo è il compromesso per una trasmissione testuale sicura. La specifica RFC 4648 definisce l'algoritmo esatto se volete i dettagli tecnici.

Quando usare Base64

Incorporare piccole immagini in HTML/CSS: Invece di far scaricare un file separato al browser, potete inserire una piccola icona inline: . Si risparmia una richiesta HTTP. Ideale per icone sotto i 2-3KB.

Inviare dati binari nelle API JSON: JSON non può contenere byte grezzi. Dovete caricare un file tramite API JSON? Codificatelo in Base64:

json

Allegati email: Questo è letteralmente lo scopo per cui Base64 è stato progettato. La codifica MIME usa Base64 per incorporare allegati binari nei messaggi email basati su testo.

JWT e token di autenticazione: I JSON Web Token usano la codifica Base64URL (una variante sicura per gli URL) per le sezioni header e payload.

Memorizzare binario in campi di testo: Colonne di testo nei database, variabili d'ambiente, file di configurazione — Base64 vi permette di mettere dati binari ovunque ci sia spazio per il testo.

Quando NON usare Base64

  • File grandi. L'aumento del 33% fa davvero male con file grandi. Un'immagine da 10MB diventa 13,3MB in Base64. Usate invece l'upload multipart form.
  • Sicurezza. Base64 non è crittografia. È banalmente reversibile. Non usatelo mai per "nascondere" password o dati sensibili. Chiunque può decodificare cGFzc3dvcmQ= in password in pochi secondi.
  • Immagini inline grandi. Per immagini sopra i ~5KB, un file separato con cache HTTP adeguata sarà più performante di un data URI Base64.

La variante URL-safe

Il Base64 standard usa + e /, che hanno un significato speciale negli URL. La variante Base64URL li sostituisce con - e _. La vedrete nei JWT e ovunque i dati Base64 appaiano negli URL.

Esempi di codice rapidi

Ecco come codificare e decodificare Base64 nei linguaggi più comuni:

javascript
python

Notate che la funzione btoa() del browser in JavaScript funziona solo con stringhe ASCII. Se dovete codificare testo Unicode, serve un passaggio extra tramite TextEncoder — questo inganna molti sviluppatori.

Errori comuni con Base64

Ecco le trappole in cui vedo cadere gli sviluppatori più spesso:

1. Presumere che Base64 sia crittografia. Non lo sottolineerò mai abbastanza. Ho visto codebase in produzione che codificano chiavi API e password in Base64, pensando di essere "protetti". Chiunque con una console del browser può decodificarle istantaneamente. Se dovete proteggere dei dati, usate crittografia vera (AES, RSA) o hashing (bcrypt, argon2).

2. Non gestire correttamente il padding. Alcune implementazioni rimuovono i segni = finali, il che può causare errori di decodifica nei parser rigorosi. Se inviate Base64 tra sistemi, accordatevi su se includere o meno il padding.

3. Usare Base64 standard negli URL. I caratteri + e / nel Base64 standard romperanno gli URL. Usate sempre la variante URL-safe (Base64URL) quando incorporate dati codificati in parametri di query o segmenti di percorso.

4. Codificare file grandi in Base64 nei payload JSON. Un file da 5MB diventa quasi 7MB dopo la codifica Base64, e l'intera stringa deve stare in memoria. Per qualsiasi cosa più grande di qualche KB, usate multipart/form-data invece.

Riferimento rapido del set di caratteri Base64

IntervalloCaratteriConteggio
MaiuscoleA-Z26
Minuscolea-z26
Cifre0-910
Simboli+ /2
Padding=1
URL-safe sostituisce- _ (al posto di + /)2

Caso d'uso reale: Incorporare font nel CSS

Un uso comune di Base64 a cui forse non pensate è incorporare font personalizzati direttamente nei file CSS. Questo evita una richiesta HTTP aggiuntiva per il file del font:

plaintext

Questa tecnica funziona bene per piccoli font di icone (sotto i 10-15KB). Per file di font più grandi, è meglio servirli separatamente in modo che il browser possa cachelarli indipendentemente.

Base64 vs altri schemi di codifica

Base64 non è l'unico modo per rappresentare dati binari come testo. Ci sono diverse alternative, e ognuna ha il suo punto di forza. Confrontiamo le principali.

Codifica Hex (Base16): L'approccio più semplice — ogni byte diventa due caratteri esadecimali (0-9, A-F). Quindi Hi diventa 4869. È semplicissimo e leggibile dagli umani, ma l'output è 100% più grande dell'input (il doppio della dimensione). L'esadecimale si vede ovunque: codici colore (#FF5733), hash SHA, indirizzi MAC e output di debug.

Base32: Usa 32 caratteri (A-Z e 2-7). L'output è circa il 60% più grande dell'input. Probabilmente l'avete già visto senza rendervene conto — quei codici a 6 cifre di Google Authenticator e altre app TOTP/2FA usano segreti codificati in Base32 sotto il cofano. È anche case-insensitive, il che lo rende ottimo per situazioni in cui gli utenti devono digitare manualmente i dati codificati.

ASCII85 / Base85: Usa 85 caratteri ASCII stampabili, producendo un output solo circa il 25% più grande dell'input. Questo è più efficiente di Base64. Git usa una variante di Base85 nel suo formato di patch binario (packfile), e i file Adobe PostScript e PDF usano internamente la codifica ASCII85. Lo svantaggio? Usa caratteri come {, } e virgolette che possono causare problemi in JSON, XML e URL.

Ecco un confronto codificando lo stesso input di 100 byte:

CodificaDimensione outputOverheadCaratteri usatiMigliore per
Hex (Base16)200 byte+100%16 (0-9, A-F)Debug, hash
Base32~160 byte+60%32 (A-Z, 2-7)Codici TOTP, contesti case-insensitive
Base64~133 byte+33%64 (A-Z, a-z, 0-9, +/)Email, JSON, data URI
Base85~125 byte+25%85 (ASCII stampabile)Packfile Git, interni PDF

Perché Base64 vince nella maggior parte dei casi? Colpisce il punto ideale: overhead ragionevole, ampiamente supportato in ogni linguaggio e piattaforma, e evita la maggior parte dei caratteri speciali che causano problemi nei formati comuni. Base85 è più compatto ma meno universalmente supportato e più difficile da usare in sicurezza nei formati di testo strutturati.

Base64 nei flussi di autenticazione

Uno degli usi più diffusi (e più fraintesi) di Base64 è nell'autenticazione HTTP Basic. Quando inviate un nome utente e una password tramite Basic Auth, il browser li concatena con i due punti e codifica il risultato in Base64.

Ecco cosa succede dietro le quinte quando fate login con nome utente admin e password secret123:

plaintext

Il server riceve quell'header, lo decodifica da Base64, divide sui due punti e verifica le credenziali. Semplice, vero? Ma ecco il punto critico: questo NON è sicuro senza HTTPS. Quella stringa Base64 è banalmente reversibile — chiunque intercetti la richiesta può decodificare YWRtaW46c2VjcmV0MTIz e ottenere la vostra password in meno di un secondo. La specifica RFC 7617 per Basic Auth avverte esplicitamente di questo.

Base64 compare anche in altri contesti di autenticazione. I token di accesso e refresh di OAuth 2.0 sono spesso codificati in Base64 (anche se questo è un dettaglio di implementazione, non un requisito). Molte chiavi API di servizi come AWS, Stripe e Google Cloud sono stringhe codificate in Base64. Ancora una volta, la codifica è per il trasporto sicuro — non per la sicurezza. Inviatele sempre tramite HTTPS e conservatele in modo sicuro.

Data URI in profondità

Abbiamo menzionato i data URI brevemente prima, ma meritano uno sguardo più approfondito. Un data URI vi permette di incorporare il contenuto di un file direttamente in HTML, CSS o JavaScript — senza bisogno di richieste HTTP esterne. La sintassi completa è:

plaintext

Il mediatype è un tipo MIME standard, il flag ;base64 dice al browser che i dati sono codificati in Base64 (senza di esso, i dati sono considerati testo codificato in URL), e è il contenuto effettivo.

Ecco degli esempi per diversi tipi di media:

Immagine PNG (più comune):

html

SVG inline (non serve Base64!):

html

Notate che gli SVG sono già testo, quindi potete codificarli in URL invece che in Base64. Questo è effettivamente più piccolo perché saltate il 33% di overhead. Gli sviluppatori furbi usano questo trucco per icone SVG semplici.

Documento PDF:

html

File audio:

html

Ora, riguardo ai limiti dei browser. Sebbene la specifica dei data URI su MDN non definisca una dimensione massima, i browser impongono i propri limiti. Chrome limita i data URI a circa 2MB nei contesti di navigazione (come iframe e pagine di primo livello). Firefox è più generoso. Per le immagini di sfondo CSS e le immagini inline, il limite pratico è la pazienza dei vostri utenti — una stringa Base64 da 500KB nel vostro file CSS è tecnicamente valida ma distruggerà assolutamente i tempi di caricamento.

Impatto sulle prestazioni: Quando Base64 fa male

Parliamo di numeri reali, perché "33% di overhead" suona astratto finché non vedete l'impatto nella pratica.

Costo di banda: Un'immagine da 50KB diventa ~67KB dopo la codifica Base64. Sono 17KB extra per immagine. Moltiplicate per una pagina con 20 icone inline e state inviando 340KB di dati non necessari. Per riferimento, è più dell'intero HTML della maggior parte delle pagine web.

Uso di memoria: Quando codificate un'immagine in Base64 e la incorporate in HTML o CSS, l'intera stringa codificata deve essere mantenuta in memoria come parte del DOM o del foglio di stile. Il browser poi la decodifica in binario, quindi brevemente state tenendo sia la versione codificata che quella decodificata. Per un'immagine da 1MB, sono circa 2,33MB solo per la stringa codificata, più 1MB per il binario decodificato — oltre 3 volte la dimensione originale del file.

Tempo di parsing: Le stringhe Base64 all'interno di HTML o CSS devono essere parsate come parte di quei documenti. Un data URI grande rende l'intero file CSS o documento HTML più lento da parsare. Secondo la guida all'ottimizzazione delle immagini di web.dev, le immagini inline dovrebbero generalmente essere sotto i 2-4KB per fornire un beneficio netto in termini di prestazioni.

Inefficienza della cache: Questo è quello che gli sviluppatori trascurano di più. Quando servite un'immagine come file separato, il browser la cachela indipendentemente — i caricamenti di pagina successivi saltano completamente il download. Ma quando codificate la stessa immagine in Base64 nel vostro file CSS, diventa parte del CSS. Se cambiate qualsiasi altra cosa nel CSS, il browser ri-scarica l'intero file, inclusi i dati dell'immagine Base64 che non sono cambiati. Perdete il caching granulare.

Ecco un benchmark approssimativo per prospettiva:

ScenarioFile separatoBase64 inline
Icona da 2KB1 richiesta HTTP extra (~5ms su HTTP/2)+0,67KB al HTML/CSS, nessuna richiesta extra
Immagine da 50KBCachata indipendentemente, multiplexata HTTP/2+17KB al CSS, ri-scaricata ad ogni modifica CSS
Foto da 500KBCachata, lazy-loadable, rendering progressivo+167KB al documento, blocca il rendering, niente lazy-load

La regola empirica: Incorporate in Base64 qualsiasi cosa sotto i 2-4KB. Servite tutto il resto come file separato. Con HTTP/2 e HTTP/3, il costo delle richieste extra è minimo, quindi la soglia si è abbassata ancora di più nel corso degli anni.

Base64 in diversi linguaggi di programmazione

Abbiamo coperto JavaScript e Python prima. Ecco come gestire Base64 in altri linguaggi popolari — ognuno in poche righe:

java
go
csharp
php
ruby

Notate come ogni linguaggio abbia Base64 nella sua libreria standard — nessun pacchetto di terze parti necessario. Questo testimonia quanto fondamentale sia questa codifica. Notate anche che Ruby ha strict_encode64 (senza interruzioni di riga) e encode64 (inserisce interruzioni di riga ogni 60 caratteri, seguendo lo standard MIME originale). La maggior parte degli usi moderni vuole la versione strict.

La storia di Base64

Base64 non è apparso dal nulla. La sua storia è legata alla storia dell'email, e capirla spiega molte delle decisioni di progettazione.

Nei primi giorni di internet, l'email (SMTP) era progettata per gestire solo testo ASCII a 7 bit — 128 caratteri, e basta. Questo andava bene per il testo in inglese, ma era completamente inutile per inviare immagini, documenti o persino testo in lingue non inglesi. Semplicemente non si potevano inviare dati binari via email.

La prima specifica formale di Base64 è apparsa nel RFC 1421 nel 1993, come parte dello standard Privacy Enhanced Mail (PEM). L'idea era semplice: convertire dati binari in un sottoinsieme di ASCII che sopravvivesse a qualsiasi sistema di trasporto basato su testo senza corruzione.

Poi è arrivato RFC 2045 nel 1996, che ha definito MIME (Multipurpose Internet Mail Extensions). MIME ha standardizzato come funzionano gli allegati email, e Base64 era la codifica principale per il contenuto binario. Ecco perché vedrete ancora header Content-Transfer-Encoding: base64 nei messaggi email grezzi oggi.

La codifica è stata perfezionata nuovamente nell'RFC 4648 (2006), che è diventato il riferimento definitivo. Questo RFC ha anche introdotto la variante URL-safe (Base64URL) e chiarito i casi limite riguardo al padding. La pagina del glossario Base64 su MDN è un buon punto di partenza se volete esplorare la specifica senza leggere gli RFC grezzi.

La cosa affascinante è che Base64 è nato da una limitazione — l'email a 7 bit — che non esiste più. L'SMTP moderno supporta il trasferimento a 8 bit e binario. Eppure Base64 è sopravvissuto ben oltre il suo scopo originale, trovando nuova vita nelle API web, nei JWT, nei data URI e in innumerevoli altri contesti. È una di quelle tecnologie che ha risolto un problema così bene che le persone continuano a trovare nuovi problemi da farle risolvere.

Provatelo voi stessi

Volete vedere Base64 in azione? Incollate qualsiasi testo o file nel nostro Base64 Encoder per vedere l'output codificato istantaneamente. Dovete decodificare qualcosa? Il Base64 Decoder se ne occupa. E se state lavorando con immagini codificate in Base64, il nostro strumento Base64 to Image vi permette di visualizzarle in anteprima direttamente nel browser.