- Le codifiche ISO, Windows ANSI e Unicode (UTF) -
 
COSA SERVE PER QUESTO TUTORIAL
Chiedi sul FORUM | Glossario cognizioni basiche di un qualsiasi linguaggio .Net
Differenze, vantaggi e svantaggi delle varie codifiche

CODIFICHE E "PLAIN TEXT"
Un primo sguardo al confuso insieme delle codifiche.

La questione degli encoding è lunga e ha sempre creato grande confusione nei programmatori, l'obiettivo di questo articolo è chiarire le idee sulle varie codifiche e come comportarsi di fronte ad ognuna. Ma prima una piccola introduzione.
La prima cosa da comprendere è che non esiste nulla di simile a ciò che viene definito plain text (puro testo), qualsiasi file di testo è in realtà una semplice sequenza di byte, e in quanto tale ha bisogno di una codifica per essere interpretata. Dunque sfatiamo il mito di "plain text", esso non è né UTF-8, né Latin-1 e neppure ASCII in quanto anche l'alfabeto inglese potrebbe essere codificato in maniera differente da come fa ASCII (si pensi ad EBCDIC). Quindi sia ben chiaro che ogni volta che si apre un file bisogna specificare la codifica che esso utilizza.

CODIFICHE A 7-8 BIT
I sistemi di codifica più semplici: ASCII, ISO e ANSI (codepage di Windows).

La codifica più conosciuta è probabilmente ASCII (acronimo per American Standard Code for Information Interchange), un set in grado di rappresentare 128 caratteri per byte (ovvero un bit viene ignorato, si tratta infatti di fatto di una codifica a 7 bit) tra i quali vi sono i principali segni di punteggiatura, le cifre decimali e le lettere dell'alfabeto inglese maiuscole e minuscole; nonostante la sua fama (principalmente dovuta alla sua diffusione come base di altri set di caratteri e alla sua semplicità) ASCII risulta di per sé scarsamente utile, in quanto non è in grado di rappresentare alcun carattere accentato, alfabeti differenti da quello inglese o tantomeno ideogrammi di lingue orientali. Per questo esistono una serie di altre codifiche che sfruttando il bit inutilizzato riescono ad rappresentare altre 128 configurazioni oltre a quelle di base del set ASCII. Le più note tra queste codifiche a byte singolo sono quelle dello standard ISO-8859 (ufficialmente ISO/IEC 8859):

  • ISO-8859-1 (Latin-1): diffusissima codifica usata per rappresentare lingue dell'Europa occidentale;
  • ISO-8859-2 (Latin-2): codifica usata per rappresentare lingue dell'Europa centrale;
  • ISO-8859-3 (Latin-3): codifica usata per rappresentare lingue dell'Europa meridionale;
  • ISO-8859-4 (Latin-4): codifica usata per rappresentare lingue dell'Europa settentrionale (più orientata alle lingue baltiche);
  • ISO-8859-5 (Latin/Cyrillic): codifica usata per rappresentare lingue slave;
  • ISO-8859-6 (Latin/Arabic): codifica usata per rappresentare la lingua araba;
  • ISO-8859-7 (Latin/Greek): codifica usata per rappresentare la lingua greca;
  • ISO-8859-8 (Latin/Hebrew): codifica usata per rappresentare la lingua ebraica;
  • ISO-8859-9 (Latin-5): simile a Latin-1 ma maggiormente orientata alle lingue turche;
  • ISO-8859-10 (Latin-6): codifica usata per rappresentare lingue dell'Europa settentrionale;
  • ISO-8859-11 (Latin/Thai): codifica usata per rappresentare la lingua thai;
  • ISO-8859-12 (Latin/Devanagari): codifica usata per rappresentare la lingua Devangagari;
  • ISO-8859-13 (Latin-7): codifica usata per rappresentare lingue baltiche;
  • ISO-8859-14 (Latin-8): codifica usata per rappresentare lingue celtiche;
  • ISO-8859-15 (Latin-9): simile a Latin-1 ma include il simbolo dell'Euro e alcune altre varianti;
  • ISO-8859-16 (Latin-10): codifica usata per rappresentare lingue dell'Europa sud-orientale;

Tutti questi set di caratteri occupano solamente un byte e risultano particolarmente utili per salvare, memorizzare o trasmettere dati che utilizzano i caratteri di un solo gruppo delle culture suddette. Le codifiche in circolazione sono poi ovviamente molte di più, ma oltre a quelle dello standard ISO vogliamo qui ricordare un tipo di codifiche con il quale ci si viene a scontrare molto spesso nell'ambito dello sviluppo: le codifiche di Windows (dette anche code page). Ecco la lista di quelle disponibili:

  • codepage 874: lingua thai;
  • codepage 1250: latino dell'Europa orientale;
  • codepage 1251: cirillico;
  • codepage 1252: latino dell'Europa occidentale (noto anche come ANSI);
  • codepage 1253: greco;
  • codepage 1254: turco;
  • codepage 1255: ebraico;
  • codepage 1256: arabo;
  • codepage 1257: baltico;
  • codepage 1258: vietnamita;

Queste codifiche sono basate su una bozza che ANSI (l'American National Standards Institute) aveva proposto ma non sono mai state standardizzate, e per questo le codifiche ISO sono sempre da preferirsi. Un problema frequente con queste codifiche ANSI è proprio il rischio di confonderle con le corrispondenti versioni ISO, in primis Latin-1 e il Windows-1252. Sebbene la codifica Windows-1252 sia un superset di Latin-1 (ovvero sia con essa del tutto compatibile) è bene non fare confusione e comunque usare sempre la versione ISO, possibilmente Latin-9, in quanto include anche il simbolo dell'Euro. Si badi però che Latin-9 non è invece compatibile con Windows-1252, ad esempio il Latin-9 il simbolo dell'euro corrisponde alla posizione 164 (A4 in esadecimale), mentre per Windows-1252 è in 128 (80 in esadecimale).

CODIFICHE MULTY-BYTE
Lo standard Unicode.

Le codifiche a byte singolo sono molto compatte ma anche molto limitate, permettono infatti un numero piuttosto limitato di caratteri (al massimo 256), fatto che genera problemi non solamente nel caso in cui si debba usare testo in lingue differenti, ma anche in una singola. In questo articolo ci occuperemo delle codifiche multi-byte definite dallo standard Unicode, che ha raggiunto l'obiettivo di riunire in un unico standard tutti i caratteri esistenti. Esso comprende 1'114'112 caratteri (da U+0 a U+10FFFF) suddivisi in 17 "piani" da 65'536 caratteri l'uno, il primo piano (piano 0) è detto Basic Multilingual Plane (abbreviato BMP) e contiene tutti caratteri necessari per rappresentare le lingue moderne, gli altri contengono caratteri supplementari o sono riservati per utilizzi futuri.
Unicode definisce due tipi di codifiche, a lunghezza fissa e a lunghezza variabile: quelle a lunghezza fissa assicurano ogni carattere occuperà una certa quantità di byte (con alcune piccole eccezioni per caratteri combinati), mentre in quelle a lunghezza variabile la lunghezza di un singolo carattere può variare.

  • UCS-2 (2-byte Universal Character Set): codifica con lunghezza fissa di due byte per carattere in grado di rappresentare solamente i caratteri del BMP, ovvero il range da U+0 a U+FFFF;
  • UTF-16 (16-bit Unicode Transformation Format): codifica che in sostanza estende UCS-2, sfruttando alcuni valori inutilizzati per permettere caratteri "surrogati", ovvero caratteri che invece di occupare due byte ne occupano 4 (per questo UTF-16 rientra nelle codifiche a lunghezza variabile); in questa maniera è possibile rappresentare tutti i 17 piani del set Unicode;
  • UCS-4 (4-byte Universal Character Set) o UTF-32 (32-bit Unicode Transformation Format): codifica che richiede 4 byte per ogni carattere, essa è ovviamente a lunghezza fissa in quanto lo spazio disponibile per un carattere è addirittura sovrabbondante rispetto a quello richiesto per rappresentare l'intero set Unicode; il vantaggio di questa codifica è che essendo a lunghezza fissa minimizza il numero di computazioni necessarie per interpretare il carattere e al contempo è in grado di rappresentare l'intero set Unicode;
  • UTF-8 (8-bit Unicode Transformation Format): codifica a lunghezza variabile in cui ogni carattere può occupare da 1 a 4 byte in grado di coprire l'intero set Unicode; tra quelle trattate finora è l'unica compatibile con il set ASCII, infatti i caratteri del set ASCII in UTF-8 vengono rappresentati nella stessa maniera; poiché ASCII richiede solamente 7-bit, il bit che avanza viene in sostanza usato per indicare se il carattere continua nel prossimo byte oppure no; con meccanismi simili UTF-8 può estendersi fino a 4 byte, comprendo l'intero set Unicode; per le lingue occidentali sono in genere sufficienti due byte, ma per coprire il BMP sono richiesti 3 byte, gli altri sono riservati per i piani meno comuni;

A questo sorge spontanea la domanda: quale usare? Innanzitutto va detto che le codifiche Unicode sono da preferirsi a quelle viste in precedenza, e in secondo luogo la risposta è che dipende. Usare UCS-2 è del tutto sconsigliabile in quanto esiste UTF-16 che è con esso compatibile ma può l'intero set Unicode. UTF-32 (o UCS-4) è usato di rado, poiché, sebbene minimizzi l'uso del processore nell'elaborazione, richiede l'impiego di 4 byte anche per rappresentare il BMP o addirittura i caratteri del set ASCII (mentre in UTF-8 bastano da 1 a 3 e in UTF-16 sono sufficienti 2).
In genere UTF-16 viene utilizzato per le stringhe di testo in memoria, in quanto è un buon compromesso tra spazio occupato ed efficienza, ma quando lo spazio occupato diventa fondamentale è preferibile UTF-8, quindi tipicamente nella trasmissione di testo attraverso la rete o quando deve essere memorizzato su disco.

WEB, HTML, XML E BOM
Le codifiche nel mondo del web e nei formanti documentali principali.

Se ci si sta chiedendo quali siano le codifiche più diffuse sul web la risposta è che c'è veramente di tutto, spesso in gran confusione. Tuttavia alcune codifiche godono di particolare privilegi, in particolare ISO-8859-1 (Latin-1), UTF-8, UTF-16 e purtroppo Windows-1252. Latin-1 è, secondo le specifiche, la codifica di default per i dati che hanno MIME type che comincia per "text/" trasmessi tramite HTTP. UTF-8 e UTF-16 sono invece un requisito obbligatorio per tutti i parser XML e in particolare, in caso la codifica non sia specificata è da intendersi come UTF-8. Infine Windows-1252 (ANSI) è la codifica di default in molti sistemi operativi Windows ed è per questo molto diffusa in editor HTML e di conseguenza sul web.
Come abbiamo detto all'inizio, non esiste un formato "puro testo", ogni volta che si riceve del testo bisogna conoscerne la codifica, ad esempio il protocollo HTTP permette di specificarla tramite l'header Content-Type, o in altri casi formati come HTML e XML permettono di specificare la codifica direttamente all'interno dei dati. Esistono poi i BOM (Byte Order Mark), ovvero una sequenza di byte che viene posta all'inizio di un file o comunque di un flusso di dati per fornire alcune indicazioni sulla codifica. Il BOM serve per determinare quale codifica è stata usata e se è Big Endian o Little Endian (ovvero se il byte più significativo sta all'inizio o alla fine, questo ha senso solamente nelle codifiche multi-byte). UTF-8 è identificato dalla sequenza esadecimale EFBBFB, UTF-16 Big Endian da FEFF, UTF-16 Little Endian da FFFE, UTF-32 BE da 0000FEFF e infine UTF-32 LE da FFFE0000. Il BOM diviene spesso un semplice indicatore che si sta usando Unicode, soprattutto per UTF-8 che in realtà non soffre di problemi di endianess. È opinione di molti che usare il BOM non sia una buona pratica in quanto la codifica utilizzata dovrebbe essere comunicata tramite altri mezzi (ad esempio l'header HTTP citato poco fa).

 

<< INDIETRO by VeNoM00