
La soluzione integrata per i tuoi SMS
Autore: Julien Buratto <julien.buratto@linkas.it>
Data: 23/07/04
Versione: 1.5-Uni
Nickname: Thecloud - 홈페이지 바로가기 (Coreano) (dovrebbe apparire circa così:
)
Se li vedi diversi, allora hai proprio bisogno di leggere questo doc :-D
Questo micro-doc cerca di spiegare in poche righe cosa sono Unicode, UTF-8, come vedere le pagine web in qualsiasi lingua (ma non spiegherò come capirle :-)) e come memorizzare il carattere ф in un database SQL.
Brevità e semplicità
(Almeno per le prime 4 pagine, le altre sono un di più).
Questo documento non vuole essere formale. Il linguaggio cerca di essere semplice, discorsivo e volontariamente impreciso nei contenuti quando, per spiegare sommariamente un concetto, siano necessarie troppe conoscenze 'formali' che possano disturbare la comprensione dell'argomento centrale.
Unicode è una lista di simboli, di disegni e di 'cose mai viste' dette, in modo generico caratteri.
Lo scopo di Unicode è stilare una lista di tutti i caratteri delle lingue del mondo, come i caratteri arabi (ש), le nostre classiche lettere “latine” (a, b, c), i caratteri russi (cirillico: Й), i caratteri greci (Σ) e tutti i caratteri degli altri paesi del mondo
La finalità di Unicode non è legata al solo settore informatico, nel senso
che non ha affinità con la programmazione 'per forza'. L'esigenza di Unicode
è nata dal voler scrivere documenti leggibili in ogni paese, indipendentemente
dal software utilizzato, ma anche dal voler creare una raccolta dei 'caratteri
del mondo' completa ai fini della standardizzazione.
Molto utile in tipografia, Unicode vorrebbe risolvere finalmente le problematiche di
trasporto di documenti da stampare in paesi diversi.
Se prendessimo un pezzo di carta e ci scrivessimo sopra la parola ciao,
così come saremmo abituati a fare in Italia, e prendessimo un aereo verso l'Arabia,
potrei far vedere vedere il mio biglietto ad un arabo.
Con questo nuovo amico straniero potrei trovarmi in 3 situazioni:
Lui riconosce i caratteri e li sa leggere, ma non sa che significato abbia la parola ciao (ovvero non capisce che è un saluto) e non sa in quale lingua sia stata scritta (inglese, francese,tedesco ?).
La persona sa leggere la parola e ,dato che conosce l'italiano, sa anche che significato ha la parola ciao (sa, in pratica, che lo stiamo salutando).
La persona non riconosce la parola ciao come una scritta, e per lui potrebbe essere tanto uno scarabocchio quanto un disegno di fantasia; non sapendo neanche in che senso girare 'dritto' il foglio, potrebbe scambiarlo per un insulto (questo è quello che succede spesso a noi con cinese,giapponese e arabo, etcetc).
Una persona che ha sottomano Unicode ha la conoscenza che ha la persona del caso 1, ovvero riconosce la parola ciao (sarebbe meglio dire che riconosce i 4 caratteri) come una parola formata da caratteri esistenti. È anche in grado di dire in che tipo di SET è stata scritta quella parola (Latin) ma non sa in che lingua è scritta (potrebbe essere, per lui, una parola inglese, tedesca, francese...etc etc).
Detto in modo 'meno esemplificativo', un set di caratteri è un elenco di caratteri che alcune lingue utilizzano per scrivere.
Tutte le lingue (o quasi) di origine latina o con parti di essa (francese,
italiano, inglese, tedesco, etc etc) usano i caratteri del set Latin.
Ci sono poi paesi con lingua di origine latina che usano questi caratteri ma
anche altri (Extended Latin) tipo questi: Ě ĝ ě
(in italiano non esistono parole con questi caratteri, tanto per capirci e neppure
i latini le usavano).
Mettiamo caso che io voglia scrivere il carattere ф e lo voglia mettere in un testo al computer.
Questo simbolo fa parte del SET dei caratteri del Cirillico (in pratica lo usano i russi, per scrivere nella loro lingua).
Nel caso in cui io volessi visualizzare questo carattere su un computer che non ce l'ha sulla tastiera (quindi non posso premere il tasto relativoҖ) mi trovo nel dilemma di come fare a metterlo nel testo.
Beh 'a mano con la penna' è facile copiare
un carattere... coi computer invece bisogna mettersi daccordo per fare in modo
che i tasti che si premono corrispondano ai caratteri che vengono visualizzati
(a quanti è capitato di premere è e veder comparire ]
).
Con i computer bisogna mettersi daccordo e definire
un modo il più universale possibile per evitare questi problemi in modo
che, su qualsiasi computer io vada, per visualizzare quel carattere, io possa
usare sempre la stessa procedura.
Se per esempio ci diamo la regola che il carattere
Җ corrisponde al 4096-esimo carattere, e quello successivo è il җ (4097)
allora se voglio scrivere il primo dei due caratteri, dovrò usare il
suo codice 4096.
Come poi inserire questo carattere nel testo in modo efficace, è un problema diverso, ma spesso i programmi di uso comune spiegano come inserire un carattere Unicode conoscendone il codice (ad esempio OpenOffice ha il menu Inserisci-Carattere speciale).
Se si usa Unicode è buona norma mettere U+ davanti al codice (U+4096) per far capire di quale elenco stiamo facendo uso.
PS: Si vedrà in seguito che 4096 non è il 4096-esimo carattere ma l'unione di 40 e 96 e che hanno un significato particolare in Unicode.
Per 'encoding' si intende una regola matematica che permette di calcolare un
codice corrispondente ad ogni carattere. Per i comuni mortali, l'encoding
si concretizza in una semplice tabella che mostra, per ogni carattere, il suo
codice corrispondente.
Ogni encoding ha spesso una tabella diversa (ma nel tempo si è cercato
di tener buone quelle vecchie estendendole (cioè allungandole) con i
nuovi caratteri introdotti mano a mano.
Abbiamo notato tutti che ci sono un sacco di Encoding diversi vero ? Ecco perchè ho scritto questo documento-nocumento :-D Per capirci meglio.
Inventiamoci un nostro set di caratteri, piccolo piccolo, e chiamiamolo Example.
Il set Example è formato dai caratteri a b c (che ci siamo inventati
anch'essi)
Ora inventiamoci un encoding per i caratteri del Set Example e chiamiamolo
Encoding-1
| Carattere |
Codifica numerica in Encoding-1 |
|---|---|
| a |
97 |
| b |
98 |
| c |
99 |
In pratica abbiamo 'inventato' 3 caratteri (a b c) e gli abbiamo associato un numero come a noi più garbava. In particolare abbiamo scelto, senza motivo, i numeri 97 98 99.
Potevamo associare, al posto dei numeri 97 98 e 99 altri numeri diversi, o un codice tipo A97 A98 e A99 ?
Certo che sì.
Sarebbe stato un encoding diverso, dello stesso set di caratteri, nulla vieta di farlo.
Due encoding sono diversi se associano, allo stesso carattere, un codice diverso;
Due encoding sono diversi se hanno set di caratteri diversi (uno il cinese e uno il Latin)
Due encoding possono essere diversi se usano modalità di associazione diverse (al posto di associare un numero, ad esempio, associano una lettera+un numero, due lettere, etc etc) (Più o meno la stessa cosa del punto 1).
Ora che abbiamo più o meno detto cosa sono i set di caratteri (una lista di caratteri), cosa è l'econding (l'algoritmo matematico che serve a memorizzare i codici dei caratteri), definiamo quale è lo scopo di Unicode.
Lo scopo di Unicode è:
Fare una lista con tutti i caratteri del mondo;
Suddividerli per 'tipologia linguistica' (Latino, Ebreo, Cirillico) o per tipologia (simboli, segnali, etc etc);
Dare un nome esteso ad ogni carattere:
Ad esempio: “Above – Combining Double Vertical Line” è il nome di
un carattere che sta sopra alle lettere (come un accento), ed è formato
da due barrettine verticali parallele, sembra un doppio apice. (il suo codice
Unicode è U+030E e visivamente è ̎ mentre il doppio apice è “ );
Dare un codice per ogni carattere:
Ad esempio: Il carattere a ha codice Unicode U+0061.
Conoscere l'encoding UTF-8 a noi non è assolutamente utile.
Ci è utile invece conoscere quali sono i caratteri Unicode (vedi sito Unicode.org);
Ci è utile sapere quale encoding il nostro computer (software
o engine SQL o browser) utilizza perchè conoscendo quale encoding
stiamo usando potremo capire se stiamo guardando le cose in modo corretto.
Se io guardo un testo codificato in modo diverso da quello che usa il mio computer, non si vedranno i caratteri (o magari se ne vedranno solo alcuni).
Se un sito è stato scritto da un cinese di Taiwan, questo potrebbe utilizzare due tipi di caratteri:
Cinese con encoding Big-5
Cinese Unicode UTF-8
Nel primo caso, Big-5, la pagina web potrà avere testi 'Latin' (francese,inglese, etcetc) e cinese tradizionale, ma non di altre lingue orientali.
Una pagina Unicode UTF-8 può contenere scritte inglesi, Cinesi, Giapponesi,
Ebree, Arabe, etc nella stessa pagina.
Questo perchè il Big-5 contiene anche i Latin ma non altre lingue orientali.
A sentire alcuni rappresentanti taiwanesi, Big-5 contiene caratteri del cinese
tradizionale che UTF-8 non ha (Non potendo io stesso verificare, se è
una bufala, vi ho avvisato!).
Per quanto riguarda i giapponesi, pare che non sia la stessa cosa.
poiché:
Nessuno tranne Unicode ha fatto una lista sei set di caratteri disponibili così completa;
Unicode è un organizzazione per la standardizzazione dei caratteri;
Lo standard Unicode è usato dalle major e si sta diffondendo su tutte le piattaforme;
UTF-8 è lo standard di codifica più diffuso;
Da qui in poi, ci sono dei contenuti aggiuntivi.
Consiglio di leggere quest'ultimo
paragrafo per risolvere i piccoli problemi quotidiani.
La visualizzazione di pagine web straniere;
La realizzazione di pagine web;
La memorizzazione di dati su server SQL;
La creazione di file XML;
Inviare e visualizzare bene il carattere € Euro con Outlook (nota su The Bat);
Vedere i quadratini al posto dei caratteri speciali..
Nel browser, selezionando la Codifica Unicode – UTF e non la Codifica Occidentale (Latin o Window). Di solito questo viene fatto in automatico dal browser su pagine che contengano una intestazione di encoding specifica.
Se in una pagina web si vuole inserire qualche carattere speciale, ci sono tre soluzioni:
Inserire &#XXXX; dove XXXX è il codice decimale ASCII del carattere da inserire
Inserire il nome della entity (se esiste) di quel carattere circondato da & e ;
Per inserire il carattere < si può usare:
Digitarlo con la tastiera (se però volete digitare 기 e non l'avete ?);
< - Codice numerico dell'encoding utilizzato (in questo
caso Latin-8859-1);
< - Il nome dell'entity è lt.
NB: Le entity sono definite come & Name ; (http://www.w3.org/TR/REC-xml#sec-references)
Attualmente HTML 4.0 ha le entity name per ogni carattere del set Latin-8859-1 più alcuni aggiuntivi, tra cui il simbolo Euro.
Conoscevi solo amp, lt, gt, quot ? Ecco ora sai che ce ne sono un sacco!
Ecco alcuni esempi per capire la potenza di vari Encoding
UTF-8 può occupare spazi diversi per memorizzare caratteri diversi, in particolare:
Usa 1 byte per memorizzare i caratteri ASCII;
Usa 2 byte per memorizzare altri 1920 caratteri (Romanico, Greco,Cirillico, etc);
Usa 3 byte per memorizzare 63488 caratteri (tra cui cinese e giapponese);
Usa 4-5-6 byte per altri 2147418112 non tutti utilizzati.
UTF-16 memorizza tutti i primi 65536 caratteri in 2 byte, gli altri in 4 byte.
UCS-2 rappresenta solo i primi 65536 caratteri Unicode e occupa sempre 2 byte.
Tutti i caratteri sono rappresentati a 4 byte e per ora tutti sono rappresetanbili.
Per scrivere questo documento sto usando OpenOffice 1.1.1 e ringrazio per lo stupendo prodotto.
Per quanto riguarda Unicode, non mi è stato però possibile inserire tutti caratteri Unicode in modo semplice e dal menu Inserisci-Carattere speciale perchè non sono presenti tutti i caratteri del set Unicode in modo indipendente dalla font. Ovvero, per inserire un carattere bisogna scegliere un font adatto.
L'help di OO defisce Unicode come:
“Unicode è un sistema per in grado di gestire i caratteri e gli elementi che compongono tutti i tipi di carattere e i sistemi di caratteri noti. Ogni carattere o elemento viene espresso con un numero di due byte. ...(continua)”.
Per quanto riguarda la versione HTML sto usando Macromedia Dreamweaver MX 2004 con update.
L'ordine è alfabetico nel caso qualcuno mi chiedesse perchè parlo prima di Coldfusion e poi di Php.
Il C ha come unità di rappresetantazione del carattere 'char' il byte di 8bit.
Sono state però aggiunte delle librerie per i wide-char (wchar_t) ad esempio che possono essere usate per risolvere il problema della trattazione dei caratteri estesi.
Supporta UTF-8 anche nel codice, così come esemplificato qui sotto:
<cfprocessingdirective pageencoding="utf-8">
<cfset ک=ArrayNew(1)>
(code by Giampaolo Bellavite)
In modo completo, Java può utilizzare i caratteri Unicode anche nel codice. Quindi i programmatori russi possono usare i caratteri cirillici per scrivere sorgente java e compilarlo. Inoltre ha tanti stream per trasferire carattere e convertire, contemporaneamente i carattere nei vari encoding.
public class ClasseEsempio {
String città;
String perchè;
In Perl si può usare la dichiarazione 'use UTF-8' . Per convertire caratteri vi sono le classi Unicode.
Php: ci sono tante funzioni per la conversione di codifica dei caratteri, ma non vi è (pare ci sia nella versione 5) un pieno supporto ai caratteri Unicode internamente. Nella visualizzazione, Php altro non deve fare che inviare i caratteri al browser, quindi mi chiedo perchè io ne stia parlando qui :-D
Attualmente supporta caratteri Unicode.
Non spiegherò come fare, ma servono la tastiera impostata in modo corretto (si veda l'howto sulla tastiera e lingua italiana), e si deve usare una font per consolle Unicode (ocio a kbd)
Questa parte era messa prima, ma data la “complessità” e l'inutilità dell'argomento, è stata spostata in fondo.
Trattiamo il carattere che abbiamo visto nell'esempio di prima, a il cui codice Unicode è U+0061.
UTF-8 è un modo per dare un numero alle cose, e usa un numero variabile di byte per ogni codice di carattere. U+0061 occupa, nella rappresentazione UTF-8 la bellezza di 1 byte mentre ם ne occupa 2.
Nella rappresentazione ASCII il carattere a occupava 1 byte (il codice ASCII 61) espresso con 8 bit 00111101.
Per poter avere un codice per ogni carattere, sono stati, col tempo, introdotti sempre nuovi tipi di codifica dei caratteri (come si è fatto cambiando le targhe delle auto in Italia per avere nuovi numeri disponibili) spesso allungando il numero di cifre usate per rappresentarli tutti.
Da ASCII a UCS-2 si è arrivati aggiungendo un nuovo blocco esadecimale davanti a quello già esistente e proseguendo nella numerazione (passando da 0xHH a 0xHH 0xJJ).
In UCS-2 la lettera a si rappresenta con 0061 (0x00 aggiunta 0x61 originale ASCII). (Ovvero due byte, 0 e 169, pari a 00000000 e 00111101).
NB: Il carattere 0x61 della lettera a siamo abituati a chiamarlo ASCII 97 che è la sua forma numerica con base 'decimale' e non 'esadecimale' nell'Encoding dei caratteri ASCII a 8 bit.
Per problemi di compatibilità con alcuni sistemi Unix e per poter rappresentare molti più caratteri si è arrivati a UTF-8 (vedi infondo per i problemi)
UCS-2 assegnava due byte (0x00 e 0x61), UCS-4 con lo stesso sistema di estensione ne usava 4.
UTF-8 associa un numero variabile di byte quindi occupa meno memoria.
Il carattere © (il suo nome in Unicode è “Copyright Sign”) ed è rappresentabile col codice Unicode U+00A9
Il suo corrispondente in notazione UCS-2 occupa 2 byte da 8 bit, 00 00 00 00
1010 1001 (0x00-0xA9).
Per capirci: 8 bit 00 00 00 00 sono 1 byte, 1010 1001 sono 1 altro byte. 00000000
è il 0x00 e 10101001 è l'esadecimale A9 (che si scrive 0xA9).
La sua rappresentazione decimale ASCII è 169 (ovvero basta convertire quel numero binario in base decimale).
Il suo corrispondente UTF-8 si ottiene aggiungendo 0xC2 (11000010). (*)
11 00 00 10 + 10 10 10 01 = 0xC2 + 0xA9
(*) Per capire come mai aggiungere C2 e non un'altra cosa, si veda dopo e si faccia riferimento alla RFC 2279 che spiega l'algoritmo matematico che sta dietro a UTF-8.
Ad esempio, coi caratteri come questo (ASCII decimale 169), compresi tra 128 e 2047 si deve usare la maschera per le sostituzioni
| 110 ??? ?? 10 ?????? |
Mettendo al posto degli ??? i bit del numero da convertire partendo da destra
e mettendo degli 0 dove ci son degli spazi vuoti: 110
00010 10 101001.
Qui si vede la maschera riempita con tre zeri in grassetto e i bit sottolineati
son quelli dell'esadecimale del carattere 0xA9.
Questa è la rappresentazione interna al nostro computer del carattere
© in modalità UTF-8.
Per capirci meglio, a voce, non si usa la rappresentazione dei caratteri Unicode
in UTF-8 ma si usa il codice Unicode in formato esadecimale UCS-2 come U+00A9.
PS: Per vedere le maschere corrispondenti, digitare su linux man 7 UTF-8
oppure guardare la RFC 2279
Trovo possa essere interessante ricercare il significato del numero 8 che compare in UTF-8. Con Giampaolo Bellavite (giampaolo@bellavite.com) si è supposto che sia:
UTF-8 L'otto è da riferirsi al numero di bit minimo necessario alla memorizzazione di un char.
UTF-16 Numero minimo di bit per i 2 caratteri dell'UTF-16 (vedi sezione dei numeri)
UCS-2 Numero di Byte necessario
UCS-4 Idem come UCS-2
Unicode: www.Unicode.org – Sito perfetto, ma diciamocelo, non ci si capisce nulla :-D
UTF-8 and Unicode FAQ for Unix/Linux http://www.cl.cam.ac.uk/~mgk25/Unicode.html#utf-8 – Simpatica pagina con 'di tutto e di più' ma un po' troppo 'rumorosa'
Entities Latin-1 del w3c: http://www.w3.org/TR/REC-html32#latin1
Xml e Encoding: http://www.w3.org/TR/REC-xml#charencoding
Unicode Howto: ftp://ftp.ilog.fr/pub/Users/haible/utf8/Unicode-HOWTO.html
RFC 2279
Unicode Faq in Italiano http://unicode.thecloud.org/
Ringrazio la mia cliente Chen MEI Yuh la quale mi ha scritto il suo nome in modo Encoded:
| Chen (Family Name) |
Unicode(UTF-8): 9673 |
Big-5: B3AF |
陳 |
| MEI (Middle Name) |
Unicode(UTF-8): 6885 |
Big-5: B1F6 |
梅 |
| Yuh (First Name) |
Unicode(UTF-8): 7389 |
Big-5: A5C9 |
玉 |
Giampaolo Bellavite per la lettura e l'aver messo in evidenza i punti meno uniformi di questo doc (che rimane, per mia colpa, disomogeneo).