Quanti byte accetta un carattere Unicode?


239

Sono un po 'confuso riguardo alle codifiche. Per quanto ne so, i vecchi caratteri ASCII hanno preso un byte per carattere. Quanti byte richiede un carattere Unicode?

Presumo che un carattere Unicode possa contenere tutti i caratteri possibili di qualsiasi lingua - ho ragione? Di quanti byte ha bisogno per personaggio?

E cosa significano UTF-7, UTF-6, UTF-16 ecc.? Sono versioni diverse di Unicode?

Ho letto l' articolo di Wikipedia su Unicode ma è abbastanza difficile per me. Non vedo l'ora di vedere una risposta semplice.



15
Siamo spiacenti, non esiste una risposta semplice. Trovo il tutto un po 'un casino. A Unicode è stato fatturato l'utilizzo di due byte e la possibilità di rappresentare tutti i caratteri, ma risulta che due byte non erano abbastanza.
Jonathan Wood,

12
"Risposta semplice": un carattere unicode richiede 1-4 byte. Unicode copre molte lingue ma non tutte. L'ultima volta che ho guardato, per esempio, Klingon non era un set di caratteri Unicode ufficiale.
Peter G.

9
Klingon non fa parte dello standard Unicode stesso, no. Utilizza invece l'Area uso privato di Uniode (U + F8D0 - U + F8FF).
Remy Lebeau,

1
Domanda del Salvatore - grazie. La mia situazione è l'archiviazione di dati tramite LMS conformi a SCORM 1.2 ... lo standard per 'cmi.suspend_data' di SCORM 1.2 è 4096 byte di dati che uno sviluppatore precedente ha ipotizzato significava che potremmo memorizzare 4096 caratteri. Oh amico aveva torto - ho appena scoperto perché il nostro bookmarking non riesce su lunghi percorsi. Quindi ora so che dal momento che stiamo usando UTF-8 ci vogliono 4 byte per carattere che ci danno 1024 caratteri.
danjah

Risposte:


147

Non vedrai una risposta semplice perché non ce n'è una.

Innanzitutto, Unicode non contiene "tutti i caratteri di ogni lingua", anche se sicuramente ci prova.

Unicode stesso è una mappatura, definisce punti di codice e un punto di codice è un numero, associato di solito a un carattere. Dico di solito perché ci sono concetti come combinare personaggi. Potresti avere familiarità con cose come accenti o umlaut. Questi possono essere usati con un altro personaggio, come ad ao a uper creare un nuovo personaggio logico. Pertanto, un carattere può essere composto da 1 o più punti di codice.

Per essere utili nei sistemi informatici, dobbiamo scegliere una rappresentazione per queste informazioni. Quelle sono le varie codifiche unicode, come utf-8, utf-16le, utf-32 ecc. Si distinguono in gran parte per la dimensione delle loro codeunit. UTF-32 è la codifica più semplice, ha una codeunit che è 32 bit, il che significa che un singolo punto di codice si adatta comodamente a una codeunit. Le altre codifiche avranno situazioni in cui un punto di codice avrà bisogno di più codeunits o quel particolare punto di codice non può essere rappresentato nella codifica (questo è un problema ad esempio con UCS-2).

A causa della flessibilità di combinare i caratteri, anche all'interno di una data codifica il numero di byte per carattere può variare a seconda del carattere e della forma di normalizzazione. Questo è un protocollo per trattare i personaggi che hanno più di una rappresentazione (si può dire "an 'a' with an accent"che è 2 punti di codice, uno dei quali è un carattere combinato o "accented 'a'"quale è un punto di codice).


1
OK. Quindi quanti byte accetta un dato carattere rappresentato in un dato punto di codice? Ad esempio, lo spazio non-break.
Nicolas Barbulesco,

I caratteri combinati rendono la vita di un programmatore un inferno quando si tratta di scrivere strlen (), substr () e altre funzioni di manipolazione di stringhe su array UTF8. Questo tipo di lavoro non sarà mai completo e sempre pieno di errori.
Nulik,

Ho scritto una demo che mostra i file codificati Windows-1252, UTF8 e UTF8-BOM interpretati con ciascuna codifica e confronta la parità tra i risultati: github.com/vladyrn/encodings_demo
Vlad

195

Stranamente, nessuno ha sottolineato come calcolare quanti byte sta prendendo un carattere Unicode. Ecco la regola per le stringhe codificate UTF-8:

Binary    Hex          Comments
0xxxxxxx  0x00..0x7F   Only byte of a 1-byte character encoding
10xxxxxx  0x80..0xBF   Continuation byte: one of 1-3 bytes following the first
110xxxxx  0xC0..0xDF   First byte of a 2-byte character encoding
1110xxxx  0xE0..0xEF   First byte of a 3-byte character encoding
11110xxx  0xF0..0xF7   First byte of a 4-byte character encoding

Quindi la risposta rapida è: ci vogliono da 1 a 4 byte, a seconda del primo che indicherà quanti byte occuperà.


8
Credo che il valore esadecimale massimo per un carattere a 4 byte sia 0xF7 (non 0xF4).
DJPJ,

Grazie mille! Stavo solo controllando + sfogliando lo standard IETF e non ho trovato nulla sulla codifica e l'articolo che stavo leggendo non è andato abbastanza nei dettagli per dire quanti bit sono usati per rappresentare il numero di codice finale punti per "personaggio".
MarcusJ,

1
Questo è ora nella seconda pagina della mia "introduzione ai nuovi membri del team", insieme ai primi due commenti esilaranti
Cee McSharpface,

1
0xF4 non è stato un errore ma un chiarimento. I punti di codice Unicode sono compresi nell'intervallo 0-0x10ffff, quindi l'ultimo punto di codice è codificato come F4 8F BF BF.
Frediano Ziglio,

38

So che questa domanda è vecchia e ha già una risposta accettata, ma voglio offrire alcuni esempi (sperando che possa essere utile a qualcuno).

Per quanto ne so, i vecchi caratteri ASCII hanno preso un byte per carattere.

Destra. In realtà, poiché ASCII è una codifica a 7 bit, supporta 128 codici (di cui 95 stampabili), quindi utilizza solo mezzo byte (se questo ha senso).

Quanti byte richiede un carattere Unicode?

Unicode associa i caratteri ai punti di codice. Non definisce come codificarli. Un file di testo non contiene caratteri Unicode, ma byte / ottetti che possono rappresentare caratteri Unicode.

Presumo che un carattere Unicode possa contenere tutti i caratteri possibili di qualsiasi lingua - ho ragione?

No. Ma quasi. Quindi sostanzialmente sì. Ma ancora no.

Di quanti byte ha bisogno per personaggio?

Come la tua seconda domanda.

E cosa significano UTF-7, UTF-6, UTF-16 ecc.? Sono alcune versioni Unicode?

No, quelli sono codifiche. Definiscono come byte / ottetti dovrebbero rappresentare i caratteri Unicode.

Un paio di esempi. Se alcuni di questi non possono essere visualizzati nel tuo browser (probabilmente perché il font non li supporta), vai a http://codepoints.net/U+1F6AA(sostituisci 1F6AAcon il punto di codice in esadecimale) per vedere un'immagine.

    • U + 0061 LATINA PICCOLA LETTERA A: a
      • Nº: 97
      • UTF-8: 61
      • UTF-16: 00 61
    • U + 00A9 SEGNO COPYRIGHT: ©
      • Nº: 169
      • UTF-8: C2 A9
      • UTF-16: 00 A9
    • U + 00AE SEGNO REGISTRATO: ®
      • Nº: 174
      • UTF-8: C2 AE
      • UTF-16: 00 AE
    • U + 1337 PHWA SILLABILE ETIOPICO:
      • Nº: 4919
      • UTF-8: E1 8C B7
      • UTF-16: 13 37
    • U + 2014 EM DASH:
      • Nº: 8212
      • UTF-8: E2 80 94
      • UTF-16: 20 14
    • U + 2030 PER SEGNO MILLE:
      • Nº: 8240
      • UTF-8: E2 80 B0
      • UTF-16: 20 30
    • U + 20AC EURO SIGN:
      • Nº: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • U + 2122 SEGNO DEL MARCHIO COMMERCIALE:
      • Nº: 8482
      • UTF-8: E2 84 A2
      • UTF-16: 21 22
    • U + 2603 PUPAZZO DI NEVE:
      • Nº: 9731
      • UTF-8: E2 98 83
      • UTF-16: 26 03
    • U + 260E TELEFONO NERO:
      • Nº: 9742
      • UTF-8: E2 98 8E
      • UTF-16: 26 0E
    • OMBRELLO U + 2614 CON GOCCE DI PIOGGIA:
      • Nº: 9748
      • UTF-8: E2 98 94
      • UTF-16: 26 14
    • U + 263A FACCIA SORRIDENTE BIANCA:
      • Nº: 9786
      • UTF-8: E2 98 BA
      • UTF-16: 26 3A
    • U + 2691 BANDIERA NERA:
      • Nº: 9873
      • UTF-8: E2 9A 91
      • UTF-16: 26 91
    • U + 269B SIMBOLO ATOM:
      • Nº: 9883
      • UTF-8: E2 9A 9B
      • UTF-16: 26 9B
    • U + 2708 AEREO:
      • Nº: 9992
      • UTF-8: E2 9C 88
      • UTF-16: 27 08
    • U + 271E CROCE LATINA BIANCA OMBRA:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • U + 3020 POSTAL MARK FACE:
      • Nº: 12320
      • UTF-8: E3 80 A0
      • UTF-16: 30 20
    • U + 8089 IDEOGRAFO UNIFICATO CJK-8089:
      • Nº: 32905
      • UTF-8: E8 82 89
      • UTF-16: 80 89
    • U + 1F4A9 MUCCHIO DI POO: 💩
      • Nº: 128169
      • UTF-8: F0 9F 92 A9
      • UTF-16: D8 3D DC A9
    • U + 1F680 ROCKET: 🚀
      • Nº: 128640
      • UTF-8: F0 9F 9A 80
      • UTF-16: D8 3D DE 80

Ok, mi sto portando via ...

Fatti divertenti:


Le unità di codice in UTF-16 sono larghe 16 bit. Li hai mostrati con uno spazio nel mezzo, che è fuorviante. La rappresentazione UTF-16 per © dovrebbe piuttosto essere 00A9invece di 00 A9(che sarebbe UTF-16BE).
Roland Illig,

Qual è la differenza? BE non significa big endian? Lo ha scritto in big endian, e quindi un file scritto in big endian UTF-16 sarebbe lo stesso di UTF-16BE, giusto?
HappyPandaFace

6
Correzioni: 1) ASCII è 7 bit, un byte è 8 bit, quindi è molto più della metà. 2) Unicode definisce come codificare i punti di codice. UTF-8, UTF-16 e UTF-32 sono definiti nello standard Unicode.
Jonathan Rosenne,

3
@JonathanRosenne Penso che intendesse usare solo la metà dei possibili valori rappresentabili con 8 bit, non che utilizza la metà dei bit.
Aritz Lopez,

2
Mi piacciono molto gli esempi. Evidenziano perché si potrebbe preferire UTF-16 rispetto a UTF-8, per esempio. Gli sviluppatori di software diversi possono selezionare codifiche diverse in base alle quali è più probabile che vengano utilizzati i caratteri Unicode. In Cina / Giappone, ad esempio, UTF-16 (2 byte) ha più senso di UTF-8 per loro, perché gli stessi personaggi spesso necessiterebbero il doppio di byte per codificare in UTF-8
microfono

29

Parlare semplicemente Unicodeè uno standard che ha assegnato un numero (chiamato punto di codice) a tutti i personaggi del mondo (è ancora in corso).

Ora devi rappresentare questi punti di codice usando byte, questo è chiamato character encoding. UTF-8, UTF-16, UTF-6sono modi di rappresentare quei personaggi.

UTF-8è la codifica di caratteri multibyte. I caratteri possono contenere da 1 a 6 byte (alcuni di questi potrebbero non essere richiesti in questo momento).

UTF-32 ogni personaggio ha 4 byte a caratteri.

UTF-16usa 16 bit per ogni carattere e rappresenta solo una parte dei caratteri Unicode chiamati BMP (per tutti gli scopi pratici è sufficiente). Java utilizza questa codifica nelle sue stringhe.


10
Unicode è un set di codici a 21 bit e 4 byte sono sufficienti per rappresentare qualsiasi carattere Unicode in UTF-8. UTF-16 usa surrogati per rappresentare personaggi al di fuori del BMP (piano multilingue di base); ha bisogno di 2 o 4 byte per rappresentare qualsiasi carattere Unicode valido. UCS-2 era l'unica variante a 16 bit di UTF-16 senza supporto per surrogati o caratteri al di fuori del BMP.
Jonathan Leffler,

1
Hai ragione. Uno originale UTF-8 aveva 6 byte per ospitare un 32 bit. In realtà non volevo complicare le cose perché era già confuso con wiki doc :)
Zimbabao

3
Questa risposta afferma che UTF-16 non può codificare punti di codice BMP. Ciò non è corretto, poiché questi possono essere codificati come in UTF-8 usando coppie surrogate. (Devi pensare all'UCS-2 obsoleto, prima che uscisse Unicode 2.0, che codificava solo punti di codice a 16 bit.) Inoltre, Java non usa del tutto UTF-16, ne usa una forma modificata dove il punto di codice 0 è codificato in modo diverso.
RDB

@rdb - È il contrario. La risposta dice che UTF-16 rappresenta il BMP.
Nicolas Barbulesco,

3
Ho sbagliato a scrivere; Avevo intenzione di dire "non BMP". L'errore nella risposta è che dice che UTF-16 rappresenta i caratteri BMP, il che è inaccurato. UTF-16 può codificare tutti i caratteri Unicode: i caratteri non BMP sono codificati tramite coppie surrogate. Forse il risponditore era confuso con UCS-2.
RDB

17

In UTF-8:

1 byte:       0 -     7F     (ASCII)
2 bytes:     80 -    7FF     (all European plus some Middle Eastern)
3 bytes:    800 -   FFFF     (multilingual plane incl. the top 1792 and private-use)
4 bytes:  10000 - 10FFFF

In UTF-16:

2 bytes:      0 -   D7FF     (multilingual plane except the top 1792 and private-use )
4 bytes:   D800 - 10FFFF

In UTF-32:

4 bytes:      0 - 10FFFF

10FFFF è l'ultimo punto di codice Unicode per definizione, ed è definito in questo modo perché è il limite tecnico di UTF-16.

È anche il punto di codice più grande che UTF-8 può codificare in 4 byte, ma l'idea alla base della codifica UTF-8 funziona anche con codifiche a 5 e 6 byte per coprire i punti di codice fino a 7FFFFFFF, vale a dire. metà di ciò che UTF-32 può.


8

In Unicode la risposta non è facile da dare. Il problema, come hai già sottolineato, sono le codifiche.

Data qualsiasi frase inglese senza caratteri diacritici, la risposta per UTF-8 sarebbe pari a tanti byte quanti caratteri e per UTF-16 sarebbe il numero di caratteri due volte.

L'unica codifica in cui (a partire da ora) possiamo fare la dichiarazione sulla dimensione è UTF-32. C'è sempre 32 bit per personaggio, anche se immagino che i punti di codice siano preparati per un futuro UTF-64 :)

Ciò che rende così difficile sono almeno due cose:

  1. personaggi composti, dove invece di usare l'entità personaggio già accentata / diacritica (À), un utente ha deciso di combinare l'accento e il carattere base (`A).
  2. punti di codice. I punti di codice sono il metodo con cui le codifiche UTF consentono di codificare più del numero di bit che di solito consentirebbe il loro nome. Ad esempio UTF-8 designa determinati byte che da soli non sono validi, ma se seguiti da un byte di continuazione valido consentiranno di descrivere un carattere oltre l'intervallo di 8 bit di 0..255. Vedi gli esempi e le codifiche eccessive di seguito nell'articolo di Wikipedia su UTF-8.
    • L'eccellente esempio dato che v'è il carattere € (punto di codice U+20ACpuò essere rappresentato sia come tre byte sequenza E2 82 ACo quattro byte sequenza F0 82 82 AC.
    • Entrambi sono validi e questo dimostra quanto sia complicata la risposta quando si parla di "Unicode" e non di una codifica specifica di Unicode, come UTF-8 o UTF-16.


4

Beh, ho appena aperto anche la pagina di Wikipedia, e nella parte introduttiva ho visto "Unicode può essere implementato da diverse codifiche di caratteri. Le codifiche più comunemente usate sono UTF-8 (che utilizza un byte per qualsiasi carattere ASCII, che ha gli stessi valori di codice nella codifica UTF-8 e ASCII e fino a quattro byte per altri caratteri), l'UCS-2 ora obsoleto (che utilizza due byte per ogni carattere ma non può codificare tutti i caratteri nell'attuale standard Unicode) "

Come dimostra questa citazione, il tuo problema è che stai presupponendo che Unicode sia un modo unico di codificare i caratteri. Esistono in realtà più forme di Unicode e, sempre in quella citazione, una di esse ha anche 1 byte per carattere, proprio come a cui sei abituato.

Quindi la tua semplice risposta che desideri è che varia.


3

Per UTF-16, il carattere necessita di quattro byte (due unità di codice) se inizia con 0xD800 o superiore; un tale personaggio è chiamato "coppia surrogata". Più specificamente, una coppia surrogata ha la forma:

[0xD800 - 0xDBFF]  [0xDC00 - 0xDFF]

dove [...] indica un'unità di codice a due byte con l'intervallo specificato. Qualsiasi cosa <= 0xD7FF è un'unità di codice (due byte). Qualsiasi cosa> = 0xE000 non è valida (tranne i marcatori DBA, probabilmente).

Vedi http://unicodebook.readthedocs.io/unicode_encodings.html , sezione 7.5.



1

Da Wiki:

UTF-8, una codifica a larghezza variabile a 8 bit che massimizza la compatibilità con ASCII;

UTF-16, una codifica a 16 bit, a larghezza variabile;

UTF-32, una codifica a larghezza fissa a 32 bit.

Queste sono le tre codifiche diverse più popolari.

  • In UTF-8 ogni carattere è codificato da 1 a 4 byte (la codifica dominante)
  • In UTF16 ogni carattere è codificato da 1 a due parole a 16 bit e
  • in UTF-32 ogni carattere è codificato come una singola parola a 32 bit.

1

Unicodeè uno standard che fornisce un numero univoco per ogni personaggio. Questi numeri univoci sono chiamati code points (che è solo un codice univoco) per tutti i caratteri esistenti nel mondo (alcuni devono ancora essere aggiunti).

Per scopi diversi, potrebbe essere necessario rappresentarlo code pointsin byte (la maggior parte dei linguaggi di programmazione lo fa), ed ecco dove Character Encodingentra in gioco.

UTF-8, UTF-16, UTF-32E così via sono tutti Character Encodings, e punti di codice di Unicode sono rappresentati in queste codifiche, in modi diversi.


UTF-8 la codifica ha una lunghezza a larghezza variabile e i caratteri, codificati al suo interno, possono occupare da 1 a 4 byte inclusi;

UTF-16ha una lunghezza variabile e caratteri, codificati al suo interno, possono richiedere 1 o 2 byte (che sono 8 o 16 bit). Questo rappresenta solo una parte di tutti i caratteri Unicode chiamati BMP (Basic Multilingual Plane) ed è sufficiente per quasi tutti i casi. Java utilizza la UTF-16codifica per le sue stringhe e caratteri;

UTF-32 ha una lunghezza fissa e ogni carattere richiede esattamente 4 byte (32 bit).

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.