ASCII è fondamentale
Originariamente 1 personaggio è sempre memorizzato come 1 byte. Un byte (8 bit) ha il potenziale per distinguere 256 possibili valori. Ma in effetti sono stati utilizzati solo i primi 7 bit. Quindi sono stati definiti solo 128 caratteri. Questo set è noto come il set di caratteri ASCII.
0x00
- 0x1F
contengono codici di sterzo (ad esempio CR, LF, STX, ETX, EOT, BEL, ...)
0x20
-0x40
contenere numeri e segni di punteggiatura
0x41
- 0x7F
contengono caratteri alfabetici per lo più
0x80
- 0xFF
l'8 bit = undefined.
Francese, tedesco e molte altre lingue richiedevano caratteri aggiuntivi. (ad esempio à, é, ç, ô, ...
) che non erano disponibili nel set di caratteri ASCII. Quindi hanno usato l'ottavo bit per definire i loro personaggi. Questo è noto come "ASCII esteso".
Il problema è che l'ulteriore 1 bit non ha abbastanza capacità per coprire tutte le lingue del mondo. Quindi ogni regione ha la sua variante ASCII. Ci sono molte codifiche ASCII estese (latin-1
è molto popolare).
domanda popolare: "è ASCII set di caratteri o è una codifica"? ASCII
è un set di caratteri. Tuttavia, nella programmazione charset
e encoding
vengono utilizzati come sinonimi. Se voglio fare riferimento a una codifica che contiene solo i caratteri ASCII e nulla più (l'8 ° bit è sempre 0): è US-ASCII
.
Unicode va oltre
Unicode è anche un set di caratteri (non una codifica). Utilizza gli stessi caratteri come lo standard ASCII, ma estende l'elenco con caratteri aggiuntivi, che assegnano a ciascun carattere un punto di codice nel formato u+xxxx
. Ha l'ambizione di contenere tutti i personaggi (e le icone popolari) utilizzati in tutto il mondo.
UTF-8, UTF-16 e UTF-32 sono codifiche che applicano la tabella di caratteri Unicode. Ma ognuno di loro ha un modo leggermente diverso su come codificarli. UTF-8 utilizzerà solo 1 byte durante la codifica di un carattere ASCII, fornendo lo stesso risultato di qualsiasi altra codifica ASCII. Ma per gli altri caratteri, utilizzerà il primo bit per indicare che seguirà un secondo byte.
GBK è una codifica, che proprio come UTF-8 utilizza più byte. Il primo byte segue lo standard ASCII, quindi vengono utilizzati solo 7 bit. L'8 ° bit viene utilizzato per indicare la presenza di un 2 ° byte, che viene utilizzato per rappresentare circa 22.000 caratteri cinesi. Ma una differenza importante, è che questo non rispetta il set di caratteri Unicode.
tipi Mime
tipi MIME sono anche spesso confuso con codifiche.
Non esiste un modo semplice per decodificare un file. Sarebbe stato ideale se tutti i file contenessero un prefisso per indicare la codifica dei dati in cui erano memorizzati. Alla fine spetta all'applicazione (o al suo sviluppatore) determinare una codifica (ad esempio US-ASCII
, UTF-8
, alcuni valori di default del sistema. ..).
Quando si inviano dati su Internet esiste lo stesso problema.Per fortuna alcuni protocolli come HTTP usano dichiarazioni di tipo mime per specificare quale tipo di dati e charset i dati utilizzano. Un tipico intestazione HTTP contiene questo:
Content-Type: text/html; charset=utf-8
Ma per text/xml
che sarebbe inutile (un parametro charset sarà nemmeno essere ignorato). I parser XML in generale leggeranno la prima riga del file, cercando il tag <?xml encoding=...
. Se è lì, riaprirà il file usando quella codifica.
Lo stesso problema esiste when sending e-mails. Una e-mail può contenere un messaggio html o semplicemente testo.
Scorciatoie
In caso di Java (e molti altri linguaggi di programmazione), oltre ai pericoli di codifiche, c'è anche la complessità della fusione byte e numeri interi in caratteri perché il loro contenuto è memorizzato in diverse categorie.
- un byte viene memorizzato come un byte con segno (range:
-128
a 127
).
- tipo
char
in java è memorizzato in 2 byte senza segno (range: 0
- 65535
)
- un flusso restituisce un numero intero nella gamma
-1
a 255
.
Se si sa che i dati contengono solo valori ASCII. Quindi con l'abilità appropriata è possibile analizzare i dati da byte a caratteri o avvolgerli immediatamente in Stringhe.
// the -1 indicates that there is no data
int input = stream.read();
if (input == -1) throw new EOFException();
// bytes must be made positive first.
byte myByte = (byte) input;
int unsignedInteger = myByte & 0xFF;
char ascii = (char)(unsignedInteger);
Il collegamento in Java è quello di utilizzare i lettori e scrittori e per specificare la codifica quando li si crea un'istanza.
// wrap your stream in a reader.
// specify the encoding
// The reader will decode the data for you
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
Come spiegato in precedenza per i file XML non importa più di tanto, perché qualsiasi DOM decente o JAXB marshaller verifica la presenza di un attributo di codifica.
La classica risorsa fuori sito per questo è il saggio di Joel Spolsky [_Lo Sviluppatore Absolute Minimum Every Software assolutamente e positivamente deve conoscere Unicode e Set di caratteri (nessuna scusa!) _] (Http://www.joelonsoftware.com/ articoli/Unicode.html). – Raedwald
È una risposta tardiva, ma ho postato alcune spiegazioni sulle codifiche e sui set di caratteri citati + anche alcune scorciatoie (ad esempio per Java) – bvdb