2009-10-09 5 views
76

Lo standard unicode ha abbastanza punti di codice in esso che sono necessari 4 byte per memorizzarli tutti. Questo è ciò che fa la codifica UTF-32. Tuttavia la codifica UTF-8 in qualche modo li comprime in spazi molto più piccoli usando qualcosa chiamata "codifica a larghezza variabile".Come funziona la codifica larghezza variabile UTF-8?

In effetti, riesce a rappresentare i primi 127 caratteri di US-ASCII in un solo byte che sembra esattamente ASCII reale, quindi è possibile interpretare molto testo ASCII come se fosse UTF-8 senza fare nulla ad esso . Trucco pulito. Quindi, come funziona?

Ho intenzione di chiedere e rispondere alla mia domanda qui perché ho appena fatto un po 'di lettura per capirlo e ho pensato che potrebbe salvare qualcun altro qualche volta. In più forse qualcuno può correggermi se ho qualcosa di sbagliato.

+7

Unicode diritto * non * richiede 32 bit per codificare tutti i suoi punti di codice. Una volta hanno rivendicato molti possibili punti di codice, ma dopo che l'UTF-8 è decollato, si sono intenzionalmente limitati a 21 bit, così che UTF-8 non supererà mai i 4 byte per carattere. Unicode richiede attualmente solo 17 bit per contenere tutti i possibili punti di codice. Senza questa limitazione, UTF-8 poteva andare a 6 byte per carattere. –

+0

@Warren: per lo più preciso, ma Unicode è un codice a 21 bit (da U + 0000 a U + 10FFFF). –

+2

@Warren: UTF-8 a 4 byte limitato potrebbe supportare fino a U + 1FFFFF. La restrizione a U + 10FFFF è stata fatta per il gusto di UTF-16. – dan04

risposta

94

Ogni byte inizia con alcuni bit che indicano se si tratta di un punto di codice a byte singolo, un punto di codice a più byte o una continuazione di un punto di codice a più byte. Come questo:

0xxx xxxx A single-byte US-ASCII code (from the first 127 characters) 

I multi-byte code-punti ciascuno Iniziamo con alcuni bit che in sostanza dicono "hey, è necessario leggere anche il prossimo byte (o due, o tre) per capire quello che sono ". Essi sono:

110x xxxx One more byte follows 
1110 xxxx Two more bytes follow 
1111 0xxx Three more bytes follow 

Infine, i byte che seguono quelli Iniziamo codici tutto simile a questa:

10xx xxxx A continuation of one of the multi-byte characters 

Dal momento che si può dire che tipo di byte che stai guardando dai primi pochi bit, poi, anche se qualcosa viene mutilato da qualche parte, non perdi l'intera sequenza.

+12

C'è dell'altro nella storia di quello - perché la codifica deve essere la codifica più breve possibile per il carattere, il che finisce per significare che i byte 0xC0 e 0xC1 non possono apparire in UTF-8, per esempio; e, in effetti, nessuno dei due può 0xF5..0xFF. Vedi le domande frequenti su UTF-8 su http://unicode.org/faq/utf_bom.html o http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf –

+0

Perché non potrebbe usarne una sola char per dire 'next char is continuation'? Se avessimo un carattere di 3 byte, sarebbe come: '1xxxxxxx 1xxxxxxx 0xxxxxxx', quindi sarebbe sprecato meno spazio. – Soaku

+1

@Soaku rende UTF-8 un cosiddetto codice "auto-sincronizzante". Ciò significa che se a causa di errori mancano parti della sequenza, è possibile rilevarlo e scartare ciò che è confuso. Se leggi un byte che inizia con 10xx e non c'è un byte "start" precedente, puoi scartarlo perché non ha senso. Se avevi un sistema come quello che hai descritto e uno dei primi byte è stato perso, potresti ritrovarti con un personaggio diverso e valido senza alcuna indicazione di alcun tipo di errore. Renderà anche facile individuare il prossimo carattere valido, oltre a correggere i byte di "continuazione" mancanti. – htmlcoderexe

1

UTF-8 era un altro sistema per la memorizzazione stringa di punti di codice Unicode, quei magici U + numeri, in memoria usando 8 byte bit. In UTF-8, ogni punto di codice da 0-127 viene memorizzato in un singolo byte . Solo i punti di codice 128 e precedenti vengono memorizzati utilizzando 2, 3, infatti, fino a 6 byte.

Estratto dal The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

+0

Questo è un buon articolo, ma sembra che Joel abbia torto per quanto riguarda la lunghezza massima della sequenza; la pagina di Wikipedia mostra solo 1..4 byte per carattere. – unwind

+4

Come ho detto sopra, quando UTF-8 è stato creato per la prima volta, Unicode ha rivendicato fino a 32 bit per i punti di codice, non perché ne avevano davvero bisogno, solo perché 32-bit è un valore conveniente e erano già saltati il limite precedente di caratteri a 16 bit. Dopo che UTF-8 si è dimostrato popolare, ha scelto di limitare per sempre il numero massimo di punti di codice a 2^21, che è il più grande valore che è possibile codificare con 4 byte dello schema UTF-8. Ci sono ancora meno di 2^17 caratteri in Unicode, quindi possiamo più che quadruplicare il numero di caratteri in Unicode con questo nuovo schema. –

+0

Ok ma non la spiegazione richiesta da OP. – Nishant

7

RFC3629 - UTF-8, a transformation format of ISO 10646 è l'autorità finale qui e ha tutte le spiegazioni.

In breve, diversi bit in ogni byte della sequenza da 1 a 4 byte con codifica UTF-8 che rappresenta un singolo carattere vengono utilizzati per indicare se si tratta di un byte finale, un byte iniziale e, in tal caso, come seguono molti byte I bit rimanenti contengono il payload.

+1

Ummmm, sciocco, ho pensato che lo standard Unicode fosse l'autorità finale su UTF-8 –

+6

Lo standard Unicode definisce lo stesso Unicode. Non definisce vari metodi, di oggi e di futuro, che possono essere utilizzati per codificare testi Unicode per una varietà di scopi (come la memorizzazione e il trasporto). UTF-8 è uno di quei metodi e il riferimento sopra è al documento che lo definisce. – azheglov

+0

RFC3629, pagina 3, sezione 3. "UTF-8 è definito dallo standard Unicode". –

Problemi correlati