unicode - utf8 - utf-8 cos'è




Le codifiche Unicode UTF-8, UTF-16 e UTF-32 differiscono nel numero di caratteri che possono memorizzare? (4)

Come tutti hanno detto, UTF-8, UTF-16 e UTF-32 possono tutti codificare tutti i punti di codice Unicode. Tuttavia, la variante UCS-2 (a volte erroneamente indicata come UCS-16) non può , e questo è quello che si trova ad esempio in Windows XP / Vista .

Vedi Wikipedia per maggiori informazioni.

Modifica: ho sbagliato su Windows, NT era l'unico a supportare UCS-2. Tuttavia, molte applicazioni Windows assumeranno una singola parola per punto di codice come in UCS-2, quindi è probabile che si riscontrino bug. Vedi un altro articolo di Wikipedia . (Grazie Jason True)

Va bene. So che questo sembra il tipico "Perché non l'ha appena fatto su Google o andare su www.unicode.org e cercarlo?" domanda, ma per una domanda così semplice la risposta mi sfugge ancora dopo aver controllato entrambe le fonti.

Sono abbastanza sicuro che tutti e tre questi sistemi di codifica supportino tutti i caratteri Unicode, ma ho bisogno di confermarlo prima di fare quella affermazione in una presentazione.

Domanda bonus: queste codifiche differiscono nel numero di caratteri che possono essere estesi per supportare?


Io personalmente controllo sempre il post di Joel su unicode, codifiche e set di caratteri in caso di dubbio.


Non esiste un carattere Unicode che può essere memorizzato in una codifica ma non in un'altra. Questo è semplicemente perché i caratteri Unicode validi sono stati limitati a ciò che può essere memorizzato in UTF-16 (che ha la più piccola capacità delle tre codifiche). In altre parole, UTF-8 e UTF-32 potrebbero essere utilizzati per rappresentare un intervallo più ampio di caratteri rispetto a UTF-16, ma non lo sono . Continua a leggere per maggiori dettagli.

UTF-8

UTF-8 è un codice a lunghezza variabile. Alcuni caratteri richiedono 1 byte, alcuni richiedono 2, alcuni 3 e alcuni 4. I byte per ogni carattere sono semplicemente scritti uno dopo l'altro come un flusso continuo di byte.

Mentre alcuni caratteri UTF-8 possono essere lunghi 4 byte, UTF-8 non può codificare 2 ^ 32 caratteri . Non è nemmeno vicino. Proverò a spiegare le ragioni di ciò.

Il software che legge un flusso UTF-8 ottiene solo una sequenza di byte - come deve decidere se i 4 byte successivi sono un singolo carattere a 4 byte, o due caratteri a 2 byte o quattro caratteri a 1 byte (o qualche altra combinazione)? Fondamentalmente questo viene fatto decidendo che certe sequenze a 1 byte non sono caratteri validi, e certe sequenze a 2 byte non sono caratteri validi, e così via. Quando appaiono queste sequenze non valide, si presume che facciano parte di una sequenza più lunga .

Hai visto un esempio piuttosto diverso di questo, ne sono sicuro: si chiama fuga. In molti linguaggi di programmazione si decide che il carattere \ nel codice sorgente di una stringa non si traduca in alcun carattere valido nel modulo "compilato" della stringa. Quando un \ si trova nel sorgente, si presume che faccia parte di una sequenza più lunga, come \n o \xFF . Nota che \x è una sequenza di 2 caratteri non valida, e \xF è una sequenza di 3 caratteri non valida, ma \xFF è una sequenza valida di 4 caratteri.

Fondamentalmente, c'è un compromesso tra avere molti personaggi e avere personaggi più brevi. Se vuoi 2 ^ 32 caratteri, devono essere lunghi in media 4 byte. Se vuoi che tutti i tuoi caratteri siano 2 byte o meno, non puoi avere più di 2 ^ 16 caratteri. UTF-8 fornisce un ragionevole compromesso: tutti ASCII caratteri ASCII (ASCII da 0 a 127) sono rappresentati con rappresentazioni a 1 byte, il che è ottimo per la compatibilità, ma sono ammessi molti più caratteri.

Come la maggior parte delle codifiche a lunghezza variabile, inclusi i tipi di sequenze di escape mostrate sopra, UTF-8 è un codice istantaneo . Ciò significa che, il decodificatore legge solo byte per byte e non appena raggiunge l'ultimo byte di un carattere, conosce il carattere (e sa che non è l'inizio di un carattere più lungo).

Ad esempio, il carattere 'A' è rappresentato usando il byte 65, e non ci sono caratteri due / tre / quattro byte il cui primo byte è 65. In caso contrario il decodificatore non sarebbe in grado di distinguere quei caratteri da un 'A 'seguito da qualcos'altro.

Ma UTF-8 è limitato ulteriormente. Assicura che la codifica di un carattere più breve non compaia mai all'interno della codifica di un carattere più lungo. Ad esempio, nessuno dei byte in un carattere di 4 byte può essere 65.

Poiché UTF-8 ha 128 caratteri di 1 byte diversi (i cui valori di byte sono 0-127), tutti i caratteri a 2, 3 e 4 byte devono essere composti esclusivamente da byte nell'intervallo 128-256. Questa è una grande limitazione. Tuttavia, consente alle funzioni di stringa orientate ai byte di operare con modifiche minime o nulle. Ad esempio, la funzione strstr() di C funziona sempre come previsto se i suoi input sono stringhe UTF-8 valide.

UTF-16

UTF-16 è anche un codice a lunghezza variabile; i suoi personaggi consumano 2 o 4 byte. I valori a 2 byte nell'intervallo 0xD800-0xDFFF sono riservati per la costruzione di caratteri a 4 byte e tutti i caratteri a 4 byte sono costituiti da due byte nell'intervallo 0xD800-0xDBFF seguito da 2 byte nell'intervallo 0xDC00-0xDFFF. Per questo motivo, Unicode non assegna alcun carattere nell'intervallo U + D800-U + DFFF.

UTF-32

UTF-32 è un codice di lunghezza fissa, con ogni carattere lungo 4 byte. Mentre questo consente la codifica di 2 ^ 32 caratteri diversi, solo i valori tra 0 e 0x10FFFF sono consentiti in questo schema.

Confronto di capacità:

  • UTF-8: 2.097.152 (in realtà 2.166.912 ma a causa di dettagli di progettazione alcuni di essi mappano la stessa cosa)
  • UTF-16: 1,112,064
  • UTF-32: 4.294.967.296 (ma limitato ai primi 1.114.112)

Il più limitato è quindi UTF-16! La definizione formale Unicode ha limitato i caratteri Unicode a quelli che possono essere codificati con UTF-16 (cioè l'intervallo da U + 0000 a U + 10FFFF escluso da U + D800 a U + DFFF). UTF-8 e UTF-32 supportano tutti questi caratteri.

Il sistema UTF-8 è infatti "artificialmente" limitato a 4 byte. Può essere esteso a 8 byte senza violare le restrizioni che ho delineato in precedenza, e ciò darebbe una capacità di 2 ^ 42. Le specifiche UTF-8 originali infatti consentivano fino a 6 byte, che danno una capacità di 2 ^ 31. Ma RFC 3629 lo ha limitato a 4 byte, poiché questo è quanto è necessario per coprire tutto ciò che fa UTF-16.

Esistono altri schemi di codifica Unicode (principalmente storici), in particolare UCS-2 (che è in grado solo di codificare U + 0000 in U + FFFF).


Tutte le codifiche UTF-8/16/32 possono mappare tutti i caratteri Unicode. Vedi http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings .

Questo articolo di IBM codifica i tuoi documenti XML in UTF-8 è molto utile, e indica se hai la scelta, è meglio scegliere UTF-8. Principalmente le ragioni sono l'ampio supporto degli strumenti, e UTF-8 solitamente può passare attraverso sistemi che non conoscono l'unicode.

Dalla sezione Cosa dicono le specifiche nell'articolo IBM :

Sia il W3C che l'IETF sono diventati di recente più determinati sulla scelta di UTF-8 prima, ultima e talvolta solo. Il modello di carattere W3C per World Wide Web 1.0: Gli stati di base, "Quando è richiesta una codifica di caratteri univoci, la codifica dei caratteri DEVE essere UTF-8, UTF-16 o UTF-32. US-ASCII è compatibile con UPF- 8 (una stringa US-ASCII è anche una stringa UTF-8, vedere [RFC 3629]), e UTF-8 è quindi appropriato se si desidera la compatibilità con US-ASCII. " In pratica, la compatibilità con US-ASCII è così utile che è quasi un requisito. Il W3C spiega saggiamente: "In altre situazioni, come per le API, UTF-16 o UTF-32 può essere più appropriato, ma i motivi possibili per scegliere uno di questi includono l'efficienza dell'elaborazione interna e l'interoperabilità con altri processi."





unicode