Giulia Guglielmi logoGiulia Guglielmi
tutti gli articoli

5 min

Cosa c'è davvero dentro un file .txt? ASCII, ANSI e il mistero del Mojibake in UTF-8

Perché un file di testo salvato a volte arriva come spazzatura tipo “è” o “’”, e come ASCII, Windows-1252 e UTF-8 decidono cosa significano davvero i tuoi byte.

In questa pagina

Ti è mai capitato di salvare un file .txt, mandarlo a qualcuno e vedere le tue parole trasformarsi in una zuppa di simboli strani? Scrivi una frase perfettamente normale come “We’ll see tomorrow.” Il tuo amico la apre sul suo computer e vede:

We’ll see tomorrow.

Questo difetto digitale ha un nome, Mojibake, ed è causato da una discrepanza nella codifica del testo. Punta a una delle idee più fondamentali dell'informatica: i computer non capiscono davvero le lettere. Capiscono solo i numeri. A seconda delle regole che un programma usa per leggere quei numeri, lo stesso identico file può mostrare due cose completamente diverse.

I computer non capiscono le lettere

Il tuo disco fisso non ha idea di cosa siano la lettera "A" o "B". Conosce solo due cose: uni e zeri. Si chiamano bit.

Come si passa quindi da un disco che memorizza solo uni e zeri alla parola "hello" mostrata sullo schermo? La risposta vive in tre nomi: ASCII, ANSI e UTF-8.

Bit, byte ed esadecimale

Un singolo bit è solo un 1 o uno 0. Mettine otto insieme e ottieni un byte:

01001000

Ogni sequenza unica di bit può rappresentare un carattere specifico. La combinatoria di base ci dice che con 8 posizioni, ciascuna 1 o 0, ottieni 2^8 = 256 combinazioni possibili, valori da 0 a 255.

Nessuno, nemmeno gli ingegneri, vuole leggere binario all'infinito. Perciò usiamo una scorciatoia chiamata esadecimale (hex). Un singolo byte si mappa in modo pulito in esattamente due cifre esadecimali:

binario 01001000  →  decimale 72  →  hex 0x48

Il prefisso 0x dice semplicemente al computer "leggi questo come esadecimale". Apri un file qualsiasi in un editor esadecimale e vedrai una griglia ordinata di codici a due cifre invece di un muro di bit.

Ma questo solleva la vera domanda: se un carattere è memorizzato come byte, e un byte è scritto come codice esadecimale, come fa il computer a decidere che 0x48 significa la lettera maiuscola H? Serve un progetto di traduzione, una codifica del testo. Ecco le tre più importanti della storia.

ASCII (1963)

Il nonno delle codifiche di testo è ASCII, l'American Standard Code for Information Interchange.

Per risparmiare spazio, ASCII usava solo 7 bit per carattere invece di 8. Sono 2^7 = 128 combinazioni. Quelle 128 posizioni coprivano tutto ciò che serviva all'inglese americano: lettere maiuscole e minuscole, cifre da 0 a 9, punteggiatura di base e una manciata di codici di controllo come Tab e Invio.

In ASCII, 0x43 significa la C maiuscola e 0x61 significa la a minuscola. Per qualche decennio è andato benissimo, finché scrivevi solo in inglese americano.

Ma se vivevi nel Regno Unito, ASCII non aveva nemmeno il simbolo della sterlina (£). E non aveva alcuno spazio per é, ñ, ü o . Man mano che i computer si diffondevano nel mondo, questo è diventato un limite netto.

L'estensione di ASCII: ANSI / Windows-1252

Ricordi che un byte vero ha 8 bit, ma ASCII ne usava solo 7? Questo lasciava 128 posizioni inutilizzate, i valori da 128 a 255.

Vari produttori e paesi iniziarono a riempire quelle posizioni vuote con i propri caratteri regionali. Lo schema di Microsoft, Windows-1252 (spesso chiamato genericamente ANSI), estese ASCII per le lingue dell'Europa occidentale:

ByteCarattere Windows-1252
0xE9é (francese, italiano)
0xF1ñ (spagnolo)
0xA3£ (sterlina britannica)

Funzionava per l'Europa occidentale, ma lasciava comunque fuori greco, cirillico, giapponese, cinese e gran parte del mondo.

UTF-8 (1993)

La svolta arrivò con Unicode, e in particolare con la codifica UTF-8.

All'inizio, gli ingegneri considerarono di dare a ogni carattere 2 byte fissi (16 bit). Questo copre decine di migliaia di caratteri, ma raddoppia all'istante la dimensione di ogni file di testo in inglese semplice. Uno spreco.

UTF-8 ha risolto con uno schema a lunghezza variabile:

  • Le lettere inglesi standard usano 1 byte, rendendo UTF-8 compatibile al 100% con ASCII.
  • Tutto il resto (accenti, altri alfabeti, emoji) si espande al volo, usando fino a 4 byte per un singolo carattere.

Oggi UTF-8 codifica oltre il 97% di tutte le pagine web.

La dimostrazione: stessi byte, due significati

Mettiamo tutto insieme. Prendiamo la nostra frase iniziale: “We’ll see tomorrow.” Nota l'apostrofo ricurvo (’) in We’ll.

Quando salvi questo come UTF-8, lettere come W, e, l, s sono memorizzate con i loro valori ASCII a un byte. Ma l'apostrofo ricurvo ha bisogno di più spazio, quindi UTF-8 memorizza quel singolo segno come tre byte:

’  →  0xE2 0x80 0x99

Ora il tuo amico apre il file in un vecchio programma cablato per leggere Windows-1252. Quella codifica si aspetta che ogni byte sia un carattere a sé, quindi decodifica i tre byte uno alla volta:

ByteWindows-1252 mostra
0xE2â
0x80
0x99

Ed è esattamente per questo che un singolo apostrofo è diventato ’.

La soluzione

La buona notizia: non devi riscrivere niente. I byte vanno bene, è solo l'interpretazione a essere sbagliata. Apri il file nel tuo editor, trova l'impostazione della codifica e forzalo a leggere il file come UTF-8 invece che come Europa occidentale / Windows-1252. Il testo torna normale.

La lezione più profonda vale la pena di tenerla a mente: un file è solo byte. I byte non hanno significato finché qualcosa non decide come leggerli. Azzecca la codifica e il Mojibake sparisce.