Quanti caratteri possono codificare UTF-8?


97

Se UTF-8 è di 8 bit, non significa che ci può essere solo un massimo di 256 caratteri diversi?

I primi 128 punti di codice sono gli stessi di ASCII. Ma dice che UTF-8 può supportare fino a milioni di caratteri?

Come funziona?


2
se potessi, per favore, rivaluta questa domanda perché tutte le risposte sono sbagliate. Leggi la mia risposta: stackoverflow.com/a/45042566/124486
Evan Carroll,

Nelle codifiche UTF-8, UTF-16, UTF-32 di Unicode, il numero è il numero di bit nelle sue unità di codice , una o più delle quali codificano un punto di codice Unicode.
Tom Blodget

1
Ho risposto a questa domanda qualche tempo fa nel tentativo di chiarirla: sarebbe fantastico se la valutassi rispetto alla risposta scelta che è letteralmente solo una singola citazione di wikipedia che non racconta l'intera storia (si spera che il mio aggiornamento è molto più chiaro)
Evan Carroll

Risposte:


135

UTF-8 non usa sempre un byte, è da 1 a 4 byte.

I primi 128 caratteri (US-ASCII) richiedono un byte.

I successivi 1.920 caratteri richiedono due byte per essere codificati. Questo copre il resto di quasi tutti gli alfabeti latini, e anche alfabeti greco, cirillico, copto, armeno, ebraico, arabo, siriaco e tana, oltre alla combinazione di segni diacritici.

Sono necessari tre byte per i caratteri nel resto del piano multilingue di base, che contiene praticamente tutti i caratteri di uso comune [12], inclusi la maggior parte dei caratteri cinesi, giapponesi e coreani [CJK].

Sono necessari quattro byte per i caratteri negli altri piani di Unicode, che includono caratteri CJK meno comuni, vari script storici, simboli matematici ed emoji (simboli pittografici).

fonte: Wikipedia


ciao @zwippie sono nuovo a questo. C'è qualcosa che non capisco.! BMP usa 2 byte che dici è 3? ho sbagliato?
chiperortiz

1
@chiperortiz, BMP è effettivamente 16 bit, quindi può essere codificato come UTF-16 con lunghezza costante per carattere (UTF-16 supporta anche andare oltre i 16 bit, ma è una pratica difficile e molte implementazioni non lo supportano). Tuttavia, per UTF-8, devi anche codificare quanto tempo sarà, quindi perdi alcuni bit. Ecco perché hai bisogno di 3 byte per codificare il BMP completo. Questo può sembrare uno spreco, ma ricorda che UTF-16 utilizza sempre 2 byte, ma UTF-8 utilizza un byte per carattere per la maggior parte dei caratteri della lingua latina. Rendendolo due volte più compatto.
sanderd17

Il punto principale della domanda dell'OP è legato al perché si chiama UTF- 8 - questo non risponde realmente.
jbyrd

39

UTF-8 utilizza 1-4 byte per carattere: un byte per i caratteri ASCII (i primi 128 valori Unicode sono gli stessi di ASCII). Ma questo richiede solo 7 bit. Se è impostato il bit più alto ("segno"), ciò indica l'inizio di una sequenza multibyte; il numero di bit alti consecutivi impostato indica il numero di byte, quindi uno 0 e i bit rimanenti contribuiscono al valore. Per gli altri byte, i due bit più alti saranno 1 e 0 e i restanti 6 bit saranno per il valore.

Quindi una sequenza di quattro byte inizierebbe con 11110 ... (e ... = tre bit per il valore) quindi tre byte con 6 bit ciascuno per il valore, producendo un valore di 21 bit. 2 ^ 21 supera il numero di caratteri Unicode, quindi tutto Unicode può essere espresso in UTF8.


@ NickL. No, intendo 3 byte. In questo esempio, se il primo byte di una sequenza multibyte inizia 1111, il primo 1 indica che è l'inizio di una sequenza multibyte, quindi il numero di 1 consecutivi dopo che indica il numero di byte aggiuntivi nella sequenza (quindi un primo byte inizierà 110, 1110 o 11110).
CodeClown42

Ho trovato la prova delle tue parole in RFC 3629. tools.ietf.org/html/rfc3629#section-3 . Tuttavia, non capisco perché devo inserire "10" all'inizio del secondo byte 110xxxxx 10xxxxxx? Perché non solo 110xxxxx xxxxxxxx?
kolobok

3
Risposta trovata in softwareengineering.stackexchange.com/questions/262227/… . Solo per motivi di sicurezza (nel caso in cui un singolo byte nel mezzo del flusso sia danneggiato)
kolobok

@kolobok Ah. Senza sicurezza si potrebbe quindi codificare un valore a 21 bit in 3 byte (3 bit che indicano la lunghezza, più 21 bit). : D Probabilmente non è così significativo, almeno per le lingue occidentali WRT.
CodeClown42

Immagino che NickL l'abbia chiesto, ma cosa è successo al resto dei bit in quel primo byte se il ... rappresenta i byte successivi invece dei bit?
c6754

26

Secondo questa tabella * UTF-8 dovrebbe supportare:

2 31 = 2.147.483.648 caratteri

Tuttavia, RFC 3629 ha limitato i valori possibili, quindi ora siamo limitati a 4 byte , il che ci dà

2 21 = 2.097.152 caratteri

Si noti che una buona parte di questi caratteri è "riservata" per un uso personalizzato, il che in realtà è molto utile per i caratteri delle icone.

* Wikipedia utilizzata mostra una tabella con 6 byte - da allora hanno aggiornato l'articolo.

11-07-2017: corretto il doppio conteggio dello stesso punto di codice codificato con più byte


Questa risposta è il doppio conteggio del numero di codifiche possibili. Dopo aver contato tutti i 2 ^ 7, non puoi contarli di nuovo in 2 ^ 11, 2 ^ 16, ecc. Il numero corretto di codifiche possibili è 2 ^ 21 (sebbene non tutte siano attualmente utilizzate).
Jimmy

@ Jimmy Sei sicuro che sto contando due volte? 0xxxxxxxdà 7 bit utilizzabili, ne 110xxxxx 10xxxxxxdà altri 11 - non c'è sovrapposizione. Il primo byte inizia con 0nel primo caso e 1nel secondo caso.
mpen

@mpen quindi quale punto di codice 00000001memorizza e cosa 11000000 100000001memorizza?
Evan Carroll

1
@EvanCarroll Uhh .... punto preso. Non sapevo che esistessero diversi modi per codificare lo stesso punto di codice.
mpen

1
Sono andato avanti e ho provato a rispondere da solo, vedi se pensi che questa sia una spiegazione migliore e rispondi alla domanda: stackoverflow.com/a/45042566/124486
Evan Carroll

21

Unicode contro UTF-8

Unicode risolve i punti di codice in caratteri. UTF-8 è un meccanismo di archiviazione per Unicode. Unicode ha una specifica. UTF-8 ha una specifica. Entrambi hanno limiti diversi. UTF-8 ha un diverso limite verso l'alto.

Unicode

Unicode è designato con "aerei". Ogni aereo trasporta 2 16 punti di codice. Ci sono 17 aerei in Unicode. Per un totale di 17 * 2^16punti di codice. Il primo aereo, piano 0 o BMP , è speciale per il peso di ciò che trasporta.

Piuttosto che spiegare tutte le sfumature, consentitemi di citare l'articolo precedente sugli aerei.

I 17 aerei possono ospitare 1.114.112 punti di codice. Di questi, 2.048 sono surrogati, 66 non sono caratteri e 137.468 sono riservati per uso privato, lasciando 974.530 per incarichi pubblici.

UTF-8

Ora torniamo all'articolo linkato sopra,

Lo schema di codifica utilizzato da UTF-8 è stato progettato con un limite molto più grande di 2 31 punti di codice (32,768 piani) e può codificare 2 21 punti di codice (32 piani) anche se limitato a 4 byte. [3] Poiché Unicode limita i punti di codice ai 17 piani che possono essere codificati da UTF-16, i punti di codice superiori a 0x10FFFF non sono validi in UTF-8 e UTF-32.

Quindi puoi vedere che puoi inserire cose in UTF-8 che non sono Unicode valide. Perché? Perché UTF-8 ospita punti di codice che Unicode non supporta nemmeno.

UTF-8, anche con una limitazione di quattro byte, supporta 2 21 punti di codice, che è molto più di17 * 2^16


18

2.164.864 "caratteri" possono essere potenzialmente codificati da UTF-8.

Questo numero è 2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21 che deriva dal modo in cui funziona la codifica:

  • I caratteri a 1 byte hanno 7 bit per la codifica 0xxxxxxx(0x00-0x7F)

  • I caratteri a 2 byte hanno 11 bit per la codifica 110xxxxx 10xxxxxx(0xC0-0xDF per il primo byte; 0x80-0xBF per il secondo)

  • I caratteri a 3 byte hanno 16 bit per la codifica 1110xxxx 10xxxxxx 10xxxxxx(0xE0-0xEF per il primo byte; 0x80-0xBF per byte di continuazione)

  • I caratteri a 4 byte hanno 21 bit per la codifica 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(0xF0-0xF7 per il primo byte; 0x80-0xBF per byte di continuazione)

Come puoi vedere, questo è significativamente più grande dell'attuale Unicode (1.112.064 caratteri).

AGGIORNARE

Il mio calcolo iniziale è sbagliato perché non considera regole aggiuntive. Vedi i commenti a questa risposta per maggiori dettagli.


2
La tua matematica non rispetta la regola UTF-8 secondo cui solo la sequenza di unità di codice più breve è autorizzata a codificare un punto di codice. Quindi, 00000001 è valido per U + 0001 ma 11110000 10000000 10000000 10000001 non lo è. Rif: Tabella 3-7. Sequenze di byte UTF-8 ben formate . Inoltre, alla domanda risponde direttamente la tabella: devi solo sommare gli intervalli. (Sono disgiunti per escludere i surrogati per UTF-16).
Tom Blodget

Tom - grazie per il tuo commento! Non ero a conoscenza di quelle restrizioni. Ho visto la tabella 3-7 e ho eseguito i numeri e sembra che ci siano 1.083.392 possibili sequenze valide.
Ruben Reyes

6

UTF-8 è una codifica a lunghezza variabile con un minimo di 8 bit per carattere.
I caratteri con punti di codice più alti impiegheranno fino a 32 bit.


2
Questo è fuorviante. Il punto di codice più lungo che puoi avere è 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx, quindi solo 21 bit possono essere usati per codificare il carattere effettivo.
Boris

5
Ho detto che i punti di codice possono richiedere fino a 32 bit per essere codificati, non ho mai affermato che (per induzione) è possibile codificare 2 ^ 32 caratteri in 32 bit UTF-8. Ma questo è piuttosto discutibile, dal momento che puoi codificare tutti i caratteri Unicode esistenti in UTF-8 e puoi codificare ancora di più se estendi UTF-8 a 48 bit (che esiste ma è deprecato), quindi non sono sicuro di quale punto fuorviante è.
inganno


2

Controlla lo standard Unicode e le informazioni correlate, come la loro voce FAQ, UTF-8 UTF-16, UTF-32 e BOM . Non è una navigazione così tranquilla, ma sono informazioni autorevoli e molto di ciò che potresti leggere su UTF-8 altrove è discutibile.

L '"8" in "UTF-8" si riferisce alla lunghezza delle unità di codice in bit. Le unità di codice sono entità utilizzate per codificare i caratteri, non necessariamente come una semplice mappatura uno a uno. UTF-8 utilizza un numero variabile di unità di codice per codificare un carattere.

La raccolta di caratteri che possono essere codificati in UTF-8 è esattamente la stessa di UTF-16 o UTF-32, vale a dire tutti i caratteri Unicode. Tutti codificano l'intero spazio di codifica Unicode, che include anche caratteri non e punti di codice non assegnati.


1

Sebbene sia d'accordo con mpen sugli attuali codici UTF-8 massimi (2.164.864) (elencati di seguito, non ho potuto commentare i suoi), è spento di 2 livelli se rimuovi le 2 principali restrizioni di UTF-8: solo 4 byte limite e codici 254 e 255 non possono essere utilizzati (ha rimosso solo il limite di 4 byte).

Il codice iniziale 254 segue la disposizione di base dei bit iniziali (flag multi-bit impostato su 1, un conteggio di 6 1 e terminale 0, nessun bit di riserva) fornendo 6 byte aggiuntivi con cui lavorare (6 gruppi 10xxxxxx, altri 2 ^ 36 codici).

Il codice iniziale 255 non segue esattamente la configurazione di base, nessun terminale 0 ma vengono utilizzati tutti i bit, fornendo 7 byte aggiuntivi (flag multi-bit impostato su 1, un conteggio di 7 1 e nessun terminale 0 perché vengono utilizzati tutti i bit ; 7 gruppi 10xxxxxx, altri 2 ^ 42 codici).

Aggiungendoli si ottiene un set di caratteri presentabili massimo finale di 4.468.982.745.216. Questo è più di tutti i caratteri in uso corrente, lingue vecchie o morte e qualsiasi lingua perduta. Qualcuno ha sceneggiatura angelica o celeste?

Inoltre ci sono codici a byte singolo che vengono trascurati / ignorati nello standard UTF-8 oltre a 254 e 255: 128-191 e pochi altri. Alcuni sono usati localmente dalla tastiera, il codice di esempio 128 di solito è un backspace che cancella. Gli altri codici iniziali (e gli intervalli associati) non sono validi per uno o più motivi ( https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences ).


0

Unicode è saldamente sposato con UTF-8. Unicode supporta specificamente 2 ^ 21 punti di codice (2.097.152 caratteri) che è esattamente lo stesso numero di punti di codice supportati da UTF-8. Entrambi i sistemi riservano lo stesso spazio 'morto' e zone limitate per i punti di codice ecc ... a partire da giugno 2018 la versione più recente, Unicode 11.0, contiene un repertorio di 137.439 caratteri

Dallo standard Unicode. Domande frequenti su Unicode

Lo standard Unicode codifica i caratteri nell'intervallo U + 0000..U + 10FFFF, che equivale a uno spazio codice a 21 bit.

Dalla pagina Wikipedia UTF-8. Descrizione UTF-8

Poiché la restrizione dello spazio codice Unicode a valori a 21 bit nel 2003, UTF-8 è definito per codificare i punti di codice da uno a quattro byte, ...


21 bit vengono arrotondati per eccesso. Unicode supporta 1.114.112 codepoint (da U + 0000 a U + 10FFFF) come dice. (A volte descritto come 17 aerei di 65536.)
Tom Blodget,

@ TomBlodget, hai ragione. il punto più rilevante di questa discussione è che UTF-8 può codificare tutti i punti attualmente definiti nello standard Unicode e sarà probabilmente in grado di farlo per un bel po 'di tempo a venire.
Nome visualizzato
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.