Newsgroup: it.comp.software.newsreader
Titolo: charset ISO

Eccellenze,
questa volta sono alle prese con gli standard ISO per i charset.
Dal momento che mi è stato spiegato che uno dei problemi cruciali da
tenere presente è la continuità storica e la compatibilità con gli
standard ed i mezzi preesistenti, mi sono fatto una ricerchina storica
sugli sviluppi di questi standard, ma - manco a dirlo - mi sono presto
imbattuto in un altro problema che non risulta abbordabile con i miei
mezzi assai limitati.
Dunque, siamo agli inizi degli anni '70 del secolo scorso. Già nel corso
del decennio precedente l'ANSI (_American National Standards Institute_)
aveva messo a punto il "padre" di tutti gli standard moderni, l'*ASCII*
(_American Standard Code for Information Interchange_, qui e nel
seguito, ovviamente, mi riferisco a quello che poi sarebbe stato
definito US-ASCII), il quale - però - era stato concepito per far fronte
alle esigenze della lingua inglese, sicché quando i computer
cominciarono a diffondersi in tutto il mondo si pose il problema di
soddisfare le esigenze di alfabeti più complessi.
Questo problema, ovviamente, andava affrontato da un organismo
internazionale, e così se ne incaricò la ISO (_International
Organization for Standardisation_), di cui l'ANSI era ed è uno dei
membri nazionali.
Per prima cosa l'ISO recepì l'ASCII, attribuendogli la sigla *ISO 646*,
poi mise mano al problema di rappresentare i caratteri peculiari
presenti nei vari alfabeti nazionali, in particolare quelli dei paesi
occidentali, che si stavano progressivamente integrando.
Come sappiamo l'ASCII è un charset codificabile con soli 7 bit, dal
momento che ogni carattere è associato ad un intero minore o uguale
all'esadecimale 7F. Per introdurre dei nuovi caratteri c'erano quindi
due possibilità:
1) usare un charset più ampio, con delle _code position_ superiori a 7F;
     - oppure -
2) sostituire alcuni caratteri non essenziali del charset ASCII con
    altri caratteri, quelli di volta in volta necessari ai vari alfabeti
    nazionali.
La prima soluzione sarebbe stata ovviamente preferibile, inoltre avrebbe
consentito a più paesi di usare tutti lo stesso charset. Tuttavia per
implementare tale soluzione si sarebbe dovuti passare da un encoding a
7 bit ad uno a 8 bit, costringendo i sistemi di mezzo mondo ad un
repentino e traumatico aggiornamento (basti pensare che ancora oggi, a
trent'anni di distanza, siamo alle prese con i "dannati" 7 bit...)
Si decise così di adottare la seconda soluzione, producendo una serie di
"ASCII nazionali". Lo metto fra virgolette perché in realtà non ha molto
senso parlare di un charset ASCII per un paese non anglofono, visto che
quella "A" sta per _American_. Diciamo piuttosto che fu l'ISO 646 ad
essere di volta in volta "nazionalizzato", producendo una serie di
standard indicati con le sigle ISO 646XY, dove dove XY sta per una
coppia di lettere che indica la lingua ed il corrispondente alfabeto:
IT, UK, DE, FR, JP, eccetera.
E qui, se permettete, piazzerei la prima domanda.
Ricordo che quando ero giovane (era passata da poco la Linea Gotica)
dopo avere installato il DOS bisognava poi "caricare la tastiera
italiana" con il comando KEYB seguito dal parametro IT. Lo si faceva,
solitamente, mettendo questo comando nel file batch "autoexec.bat", che
veniva eseguito automaticamente all'avvio del pc.
Ora, se confronto una tastiera americana con la mia tastiera (che,
ovviamente, è italiana) scopro che le differenze fra le tastiere sono le
stesse che sussistono fra l'ISO 646IT e l'ISO 646(US), cioè l'US-ASCII.
Ne deduco che quando si eseguiva il comando
     KEYB XY
si stava dicendo alla macchina di non usare l'ISO 646(US), bensì l'ISO
646XY.
Ho ragionato bene?
Andiamo avanti con la nostra "storia".
In seguito questa scelta, che pure all'epoca era stata necessaria,
mostrò i suoi limiti, soprattutto quelli legati alla impossibilità di
scambiare documenti a livello internazione senza generare inevitabili
ambiguità e conflitti, dal momento che una stessa _code position_ poteva
essere visualizzata e stampata in modo diverso a seconda del paese in
cui veniva "letto" il documento.
Allora la ISO cominciò a prendere in considerazione la possibilità di
estendere il charset, rendendolo codificabile con 8 bit anziché 7, e
venendo così a disporre di tutti le _code positions_ fino a FF.
Nacque così lo standard 8859. Nel frattempo la ISO aveva cominciato a
collaborare strettamente con la IEC (_International Electrotechnical
Commission_) per mezzo di una commissione congiunta, per cui esso si
chiamò *ISO/IEC 8859*.
Questo protocollo ha le seguenti caratteristiche:
1) usa le posizioni fino a 7F per codificare il solito ASCII;
2) non fornisce specifiche per le posizioni comprese fra 80 e 9F;
3) colloca i caratteri alfabetici aggiuntivi dalla posizione A0 fino a
    FF.
Ne consegue che esso produce una serie di "dialetti" a seconda di quali
caratteri si vogliano aggiungere e di come si vogliano "riempire" i
codici numerici che non vengono specficati:
1) Per quanto riguarda i caratteri alfabetici aggiuntivi da collocare
fra A0 e FF, i primi ad essere aggiunti furono quelli dei paesi
dell'Europa Occidentale, i quali fanno uso dell'alfabeto latino di base
oltre ai caratteri peculiari presenti nell'italiano, spagnolo, francese,
tedesco eccetera. Si ottenne così il protocollo 8859-1 ("West European"
o "Latin 1"), seguito poi dall'8859-2 ("Central European", o "Latin 2")
e così via, fino al recente 8859-15 ("Euro", o "Latin 9"), passando per
l'8859-5 ("Latin/Cyrillic"), 8859-6 ("Latin/Arabic"), 8859-7
("Latin/Greek") e l'8859-8 ("Latin/Hebrew").
2) Quanto ai codici compresi fra 80 e 9F si è imposta la scelta di due
diverse "autorità". La Microsoft ha deciso, per i prodotti Windows, di
introdurre dei caratteri di tipo alfabetico, producendo il protocollo
CP1252, che è un sovrainsieme dell'ISO/IEC 8859-1. Però quando la IANA
(_Internet Assigned Numbers Authority_) ha deciso di adottare tutti i
protocolli ISO/IEC 8859-X, ha deciso di "completarli" tutti nello stesso
modo, collocando nelle posizioni non definite alcuni caratteri di
controllo. I protcolli ISO/IEC 8859-X così completati vengono definiti
dalla IANA con la sigla *ISO-8859-X* (occhio al trattino!), mentre la
variante della Microsoft dell'ISO/IEC 8859-1 viene definita
*Windows-1252*.
Tutto chiaro?
Non per me, che non riesco a venire a capo di una questione che provo ad
esporre qui di seguito.
In questo momento io sto usando Windows XP con una tastiera italiana e,
se ho ben compreso, tutti i programmi che girano su questa piattaforma
fanno uso di un qualche "dialetto" dell'ISO/IEC 8859, in particolare
l'8859-1.
Me ne rendo conto se uso la "Mappa caratteri", e d'altra parte il mio
newsreader è settato proprio in questo modo.
*Ma* i vari standard 8859 hanno tutti in comune fra di loro il fatto di
avere codificato fino alla posizione 7F *non* un "ASCII nazionale", cioè
uno standard 646XY, *bensì* il caro vecchio *US-ASCII*.
Cosa accade, allora, quando io batto, che so, il tasto con su la lettera
"è"?
Non è possibile che venga immesso un codice inferiore a 7F, poiché quei
codici sono occupati dal charset US-ASCII, dove di lettere accentate non
ce ne sono.
D'altra parte, però, l'elettronica delle tastiere è sempre quella, a
prescindere da cosa c'è "disegnato" sui vari tasti. Se prendo una
tastiera "americana" e batto il tasto che si trova nella stessa
posizione, la sequenza binaria che viene trasmessa alla macchina è la
stessa, e corrisponde - diciamo così - ad un certo "codice Alt".
Però se siamo in America quel certo "codice Alt" produce un codice
inferiore a 7F, mentre se siamo in Italia quello stesso "codice Alt"
produce un codice che - per forza di cose - deve essere superiore a 7F,
anzi, addiruttura maggiore o uguale ad A0.
Se da una parte questa "illuminazione" (ammesso che di illuminazione si
tratti, e non stia prendendo un granchio colossale) mi permette di
capire per quale ragione i miei dotti interlocutori mi hanno detto a più
riprese che usando le lettere accentate sulla tastiera automaticamente
si "abbandona" il charset US-ASCII, allo stesso tempo mi sorgono non
pochi dubbi su come possa funzionare questa "diavoleria", poiché mi
sembra di poter escludere a priori che sia stata "caricata" una tastiera
con un comando KEYB o qualcosa di analogo.
Qui non si tratta, infatti, di usare un charset piuttosto che un altro,
mantenendo costante l'associazione fra il "codice Alt" e la _code
position_. Si tratta invece di fare una operazione che dev'essere molto
più complessa, poiché bisognerebbe "intercettare" i vari "codici Alt" e
"indirizzarli" al di sopra o al di sotto della _code position_ 7F.
Ma davvero sono così complicate le piattaforme moderne?
Grazie ancora per l'attenzione e per le gentili risposte che mi sono
state date negli altri thread.
-- 
Ciao.
D. 

 Ma davvero sono così complicate le piattaforme moderne? 
O forse non sono riuscito a capire bene quello che chiedevi

"è"?
Il sistema sa che tu hai una tastiera italiana e traduce quel tasto nel
corrispondente carattere UNICODE. Tra l'altro Windowx XP ti permette di
cambiare al volo la tastiera con la "barra della lingua".
Se un'applicazione gestisce completamente UNICODE non c'è nessun problema.
Invece per le applicazioni che non lo gesticono appieno (ovvero che
internamente hanno le stringhe di caratteri di 1 byte e non di 2 byte
UNICODE) il rich edit restistuisce all'applicazione i caratteri già
convertiti nel "code page" della macchina (se non diversamente specificato).
Cosa vuol dire? Supponiamo che tu abbia un'applicazione che non supporta
UNICODE in modo completo:
- attraverso la mappa dei caratteri inserisci un carattere giapponese nel
tuo editor (rich edit)
- lo vedi senza problemi
- fai un'operazione che richiede all'applicazione l'uso del testo inserito
- la tua applicazione chiede al rich edit il testo inserito ma lo chiede
non in UNICODE
- il rich edit converte i caratteri digitati (che lui conserva in UNICODE)
nei caratteri del "code page" di sistema (ad esempio 1252, ovvero quello
predefinito su tutti i sistemi europei)
- il carattere giapponese viene converito in ?
- se invece l'applicazione richiede il testo in UNICODE va tutto bene
- l'applicazione ha la possibilità di chiedere al rich edit un testo non
UNICODE ma di un dato code-page, ad esempio quello dell'alfabeto
giapponese, se installato; in questo caso ottiene codici validi per quel
charset (ad ogni charset installato corrisponde un code-page)
-- 
-antonio-
www.geminisoft.com
(email valida sul mio sito)

 perche dipende dal supporto UNICODE del tuo programma.
'Spetta, che forse comincio a capire.
Il post che sto scrivendo ora è settato su ISO-8859-15 (Latin 9).
Adesso vado in mappa caratteri e compongo un termine in cirillico, che
poi mi copio nel post. Eccolo qua:
     ДомашняяСтраница
Nessuno di questi caratteri si trova nel charset ISO-8859-15 o in
Windows-1252. Se stessi usando il charset ISO-8859-5 (Latin/Cyrillic) li
avrei tutti a disposizione, ma non è quello il charset di default con
cui escono i miei post.
Nonostante ciò, il copia-incolla ha funzionato perfettamente perché, se
ho capito, l'editor di OE gestisce il testo attraverso il _rich edit_,
il quale rappresenta internamente i caratteri per mezzo del charset
Unicode, con *2 byte*.
Cosi, ad esempio, il carattere "Д", che corrisponde al codice U+0414 (da
leggersi: Unicode 0x0414, visto che si tratta di una rappresentazione
esadecimale) in questo momento se ne sta caricato in RAM occupando due
byte che hanno, rispettivamente, i valori esadecimali 0x04 e 0x14.
(Qui mi fermo un attimo per osservare che questo Unicode di Windows è,
per così dire, una versione "ridotta", poiché nella mappa caratteri sono
codificati i caratteri fino alla _code position_ 0xFFFF, che è il
massimo che si possa fare con 2 byte. Beh, poco male: non potremo usare
igeroglifici ed i caratteri cuneiformi :-) )
A questo punto faccio l'"azzardo", e provo a salvare il post nella
cartella "Bozze".
OE, che ha tutti i caratteri in formato Unicode, tenta di salvarli
usando il charset di default, ma si accorge che in esso non ci sono
tutti, e mi dice:
«Il messaggio contiene testo con un set di caratteri diverso da quello
predefinito. Per l'invio di questo messaggio sono disponibili le
seguenti opzioni: 1) Invia come Unicode [...], 2) Formato attuale [...]»
Seleziono la prima opzione, il messaggio viene salvato in "Bozze", vado
a leggere gli header e trovo, giustamente:
Content-Type: [...] charset="utf-8" [...]
A questo punto si pone una domanda che, se la risposta è come credo,
potrebbe togliermi un bel po' di dubbi. La domanda è questa:
come è registrato questo testo sul disco rigido?
La soluzione più semplice sarebbe quella di assegnare 2 byte per ogni
carattere. Ma a me viene difficile pensare che OE, per il semplice fatto
che gli ho indicato "utf-8" come charset, vada a codifcare con 2 byte
anche tutti i caratteri ASCII che sto scrivendo in questo momento,
poiché in tal caso il post dovrebbe raddoppiare o dimezzare le proprie
dimensioni al variare del charset prescelto.
E c'è un'altra ragione per la quale non credo che la soluzione sia così
"banale". Ti ricordi quando abbiamo detto che a rigore l'UTF-8 dovrebbe
essere solo un metodo di _encoding_, mentre il _charset_ dovrebbe essere
"Unicode"? Tu mi hai detto che "le cose sono andate così", ma ti devo
confessare che non sono del tutto sicuro che quando hanno definito il
protocollo MIME abbiano fatto certe scelte del tutto a caso, o solo per
ragioni di continuità storica.
Infatti è vero che l'UTF-8 dovrebbe servire per codificare in sequenze
binarie i numeri interi associati ai vari caratteri, usando un numero
variabile di byte per ogni carattere. Non vorrei, però, che nel
frattempo si sia deciso di usarlo molto più "intensamente", facendone un
vero e proprio _charset_. D'altra parte 'sto numero intero che viene
associato ad un carattere alla fine deve essere rappresentato con una
sequenza binaria, per cui un _encoding_ definisce pur sempre un
_charset_, non appena si decida di "leggere" i singoli byte come numeri
interi scritti in base 2.
Se le cose stanno così, il carattere "a", che corrisponde al codice
U+0061 in questo momento è caricato in RAM occupando due byte che hanno
i valori 0x00 e 0x61, ma se ne sta registrato sul disco rigido occupando
un solo byte nel quale è memorizzato il valore 0x61, cioè 01100001.
Invece il carattere "Д", che - come abbiamo visto - corrisponde al
codice U+0414, ha bisogno di 2 byte anche sul disco rigido.
Se andiamo a leggere le specifiche UTF-8 vediamo che se il codice
Unicode in rappresentazione binaria assume la forma:
     00000yyy   yyxxxxxx
allora l'_encoding_ attraverso l'UTF-8 lo trasforma nei seguenti 2 byte:
     110yyyyy   10xxxxxx
Nel nostro caso il carattere "Д" in rappresentazione binaria Unicode è
dato dai seguenti due byte:
     00000100   00010100
e quindi la sequenza UTF-8 corrispondente è:
     11010000   10010100
sicché in esadecimale abbiamo i 2 byte 0xD0 e 0x94.
E' vero che in questo modo il contenuto binario della RAM non coincide
con quello del disco rigido, ma in cambio abbiamo due fondamentali
vantaggi:
1) le dimensioni del file sul disco rigido aumentano solo nella misura
    in cui si usano dei caratteri "lontani" dall'ASCII;
2) le sequenze binarie contenute sul disco rigido sono già pronte per
    essere inviate secondo lo standard UTF-8 (a parte la questione del
    _byte order mark_, che non mi pare il caso di tirar fuori).
Insomma, se la congettura su cui ho costruito questa "fantasia" è
fondata, la mappa fra caratteri e codici Unicode costituisce, per così
dire, un "charset per la RAM" (e per le .dll del _rich edit_), mentre la
mappa fra i caratteri e le sequenze UTF-8 oltre ad essere un protocollo
per la "spedizione" è anche un "charset per l'HD".
Mi rendo conto che è una cosa un po' azzardata, ma si spiegherebbero un
bel po' di cosette.
Tu che dici? Acqua o fuochino? :-)
-- 
Ciao.
D. 

 anche se magari  non te ne rendi pienamente conto.
Sì, effettivamente in qualche modo il sistema lo deve "sapere" che sto
usando una tastiera "italiana".
Ma facevo fatica ad "immaginarmi" la cosa. Una delle ragioni è che mi
mancava un dato fondamentale, ovvero il fatto che nei sistemi NT (e
quindi XP, 2000, eccetera) la "rappresentazione interna" dei caratteri
fa uso della codifica Unicode a 2 byte. Adesso che Antonio me l'ha
spiegato, sono riuscito a fare ancora un po' di strada (ma poca :-) ).
Probabilmente l'informazione che dicevo io se ne sta scritta da qualche
parte nel registro, e viene impiegata dalle .dll in cui sono contenute
le librerie del _rich edit_ (fino a poche ore fa nemmeno sapevo che
esistesse, 'sto _rich edit_, e mi sono documentato in fretta: abbi
pazienza se ho detto un'altra stupidaggine).
Grazie e... a domani (spero non sia considerato una minaccia ;-) )
-- 
Ciao.
D. 

Tu che dici? Acqua o fuochino? :-)
Acqua :-)
Per me uft-7 e utf-8 sono solo un modo comodo per spedire i due byte
unicode attraverso canali 7-bit o 8-bit in modo sicuro ed efficiente.


 Acqua :-)
Ok, accetto il verdetto di chi queste cose le *fa*, poiche il fare è
sempre una garanzia (se tu non avessi capito qualcosa ora Pimmy non
funzionerebbe, a prescindere dalle mie chiacchiere :-) ). Se solo ti
andasse di spiegarmi un po' meglio come è fatto quel formato che sta nei
dbx di OE ed in che cosa differisce da UTF-8... Dài, è Natale, e sono
tutti più buoni, anche i programmatori :-)
-- 
Ciao.
D. 

 O forse non sono riuscito a capire bene quello che chiedevi
Provo a spiegarmi meglio.
Nel mio post dicevo che quando uno decide di "estendere" l'ASCII,
introducendo dei nuovi caratteri, ha di fronte a sé due strade
possibili:
1) se vuole restare a 7 bit bisogna che prenda alcuni caratteri ASCII,
li butti via, e metta al loro posto i nuovi caratteri;
2) se invece si "rassegna" a passare a 8 bit allora può sfruttare le
posizioni del charset da 0x80 fino a 0xFF, lasciando inalterato tutto il
blocco ASCII, che sta sotto la posizione 0x7F.
Ora, queste due soluzioni sono mutuamente *esclusive*: o si adotta una o
si adotta l'altra.
Supponiamo, ad esempio, di voler aggiungere "è" all'ASCII senza
oltrapassare i 7 bit. Cerchiamo al di sotto della posizione 7F un
carattere "sacrificabile" e decidiamo che il carattere "}", che sta
nella posizione 7D,  è molto meno importante di "è". Quindi eliminiamo
"}" mettendoci al suo posto la "è". Da quel momento il carattere "}" non
esisterà più nel nostro charset IT-ASCII (o meglio ISO 646IT) ed al suo
posto comparirà la "è".
Se invece avessimo deciso di passare ad una codifica ad 8 bit, allora
avremmo potuto piazzare la "è" in posizione E8, lasciando il carattere
"}" dov'era. In questo modo avremmo ottenuto il charset ISO-8859-1 (o
uno dei suoi "dialetti").
Vedi bene che *o* faccio una cosa *o* faccio l'altra.
Se vado a modificare ciò che sta sotto la posizione 7F (orientandomi
sulla "soluzione 646"), poi mi precludo definitivamente la possibilità
di usare la codifica ad 8 bit (cioè la "soluzione 8859"). La prima è una
*variante* dell'ASCII, mentre la seconda ne è una *estensione*.
Ora, se fosse vero che "sotto" a Windows XP c'è ancora il DOS "vero",
cioè qualcosa che ha a che fare con il comando KEYB o un comando
equivalente, noi avremmo adottato una *variante*, e non potremmo più
effettuare delle *estensioni*. Ad esempio ci verrebbe a mancare il
carattere ASCII  "}" nella posizione 7D.
Per questo dicevo che "sotto" a Windows XP non ci può essere qualcosa
che funziona "davvero" come il DOS, per lo meno dal punto di vista della
gestione dei caratteri. Poi Antonio mi ha spiegato che "sotto" c'è
addirittura sua maestà l'Unicode e allora la cosa si è definitivamente
chiarita: _ubi maior minor cessat_ - come dicono quelli che hanno 
studiato.
(Btw, perché ci si riferisce a quello standard come Unicode, quando di 
fatto si tratta dell'ISO/IEC 10646? E' la ISO che si è adeguata agli 
standard del _Consortium_, o è quest'ultimo che si è "sincronizzato" con 
la ISO? E se hanno fatto le cose assieme, perché si nomina il protocollo 
del _Consortium_, che è pur sempre un ente "privato", quando invece la 
ISO è l'organismo internazionale "ufficiale"? Sono le grandi aziende 
americane che stanno cercando di imporsi sull'ISO, oppure è l'ISO che 
con i suoi tempi geologici e la sua burocrazia faraginosa si sta facendo 
superare dal "mercato"?)
-- 
Ciao.
D. 


Ecco perché son diventato scettico. :o)
-- 
     * b *
   *   y   *
 *   Piero   *
[/rebus sic stantibus/] 

 ...poi l'ha distribuito ed il server tedesco l'ha accettato. :-/
Sei coraggioso: se i krukki si accorgono dello scherzo che gli hai
combinato ti arrivano in giardino con una Panzer Division :-D
Grazie per il "feedback".
-- 
Ciao.
D. 

tutti più buoni, anche i programmatori :-)
Nel formato dbx l'email è salvata esattamente come te l'aspetti, nulla di
strano, non è salvata in UNICODE (due byte per ogni carattere). E' solo
salvata a pezzi ma questo è un cosa ininfluente ai fini della discussione.


 Grazie per il "feedback".
È stato un piacere. :-D
P.S. Toglimi una curiosità: dove sono finiti gli spazi a fine riga del 
format=flowed? Te li ha /mangiati/ Fidolook? <eg>
-- 
     * b *
   *   y   *
 *   Piero   *
[/deus ex machina/]