2012-03-02 38 views
54

Qual è il numero massimo di byte per un singolo carattere con codifica UTF-8?Qual è il numero massimo di byte per un carattere con codifica UTF-8?

Codirò i byte di una stringa codificata in UTF-8 e quindi dovrò essere in grado di calcolare il numero massimo di byte per una stringa codificata UTF-8.

Qualcuno potrebbe confermare il numero massimo di byte per un singolo UTF-8 caratteri codificati favore

+1

Hai * guardato * a risorse comuni, come [articolo UTF-8 di Wikipedia] (http://en.wikipedia.org/wiki/UTF-8), prima ... giusto? –

+3

Ho letto diversi articoli che hanno dato risposte miste ... In realtà ho avuto l'impressione che la risposta fosse 3 quindi sono molto contento di aver chiesto – Edd

+1

Qui lascerò un link di youtube, con Tom Scott's Personaggi, Simboli, Unicode miracolo: https: //goo.gl/sUr1Hf. Si arriva a sentire e vedere come tutto si sta evolvendo dalla codifica dei caratteri ASCII a utf-8. – Roylee

risposta

61

Il numero massimo di byte per carattere è 4 secondo RFC3629 che ha limitato la tabella caratteri a U+10FFFF:

In UTF-8, i caratteri dell'intervallo U + 0000..U + 10FFFF (l'intervallo accessibile UTF-16 ) sono codificati utilizzando sequenze da 1 a 4 ottetti.

(La specifica originale permesso fino a sei byte codici di carattere per i punti di codice ultime U+10FFFF.)

caratteri con un codice inferiore a 128 richiederà solo 1 byte, ed i successivi 1920 codici di carattere richiede 2 solo byte. A meno che tu non stia lavorando con un linguaggio esoterico, moltiplicare il numero di caratteri per 4 sarà una sovrastima significativa.

+2

Che cos'è per te "linguaggio esoterico"? Qualsiasi linguaggio che esisterebbe nel mondo reale o un testo che cambia tra le diverse lingue del mondo? Se uno sviluppatore di una funzione da UTF-8 a stringa sceglie 2, 3 o 4 come moltiplicatore se esegue un'eccessiva allocazione e riduce il risultato dopo la conversione effettiva? –

+1

@rinntech di 'linguaggio esoterico' indica un linguaggio che ha molti caratteri unicode di alto valore (qualcosa che si trova in fondo all'elenco: http://unicode-table.com/en/sections/). Se è necessario sovra-allocare, scegliere 4. Si potrebbe fare un doppio passaggio, uno per vedere quanti byte avrete bisogno e allocare, quindi un altro per fare la codifica; potrebbe essere meglio che allocare ~ 4 volte la RAM necessaria. – matiu

+4

Cerca sempre di gestire il caso peggiore: http://www.hacker9.com/single-message-can-crash-whatsapp.html –

22

Senza ulteriori contesto, direi che il numero massimo di byte per un personaggio in UTF-8 è

risposta: 6 byte

L'autore della risposta accettata rilevare correttamente questo come il " specifica originale ", ma ritengo che questo sia fuorviante per il lettore, perché per quanto ne so, questa è ancora la specifica attuale e corretta, per wikipedia e per a Google book on UTF-8 in Java.

RFC riferimento negli stati risposta accettato che solo quattro byte sono rilevanti per una codifica UTF-16, di modo che è corretto solo se si aggiunge contesto

risposta se traducendo solo caratteri UTF-16 a UTF- 8: 4 byte

Ora, tutti i caratteri che possono essere rappresentati da UTF-16 sono utili? Secondo wikipedia again, unicode può rappresentare fino a x10FFFF punti di codice. Quindi, incluso 0, ciò significa che possiamo farlo con questi byte: F FF FF, cioè due byte e mezzo o 20 bit. Guardando indietro alle specifiche UTF-8, vediamo che possiamo rappresentare 20 bit con un massimo di quattro byte codificati in UTF-8. Così

risposta se copre tutta unicode: 4 byte

Ma, in Java <= v7, si parla di un massimo di 3 byte per rappresentare unicode con UTF-8? Questo perché la specifica unicode originale definiva solo il piano multilingue multi-lingua (BMP), cioè una versione precedente di unicode o sottoinsieme di unicode moderno. Così

risposta se rappresentano solo unicode originale, il BMP: 3 byte

Ma, i colloqui OP di andare nella direzione opposta. Non da caratteri a byte UTF-8, ma da byte UTF-8 a una rappresentazione "String" di byte. Forse l'autore della risposta accettata ha ottenuto questo dal contesto della domanda, ma questo non è necessariamente ovvio, quindi potrebbe confondere il lettore casuale di questa domanda.

Passando da UTF-8 alla codifica nativa, dobbiamo osservare come viene implementata la "stringa". Alcuni linguaggi, come Python> = 3, rappresentano ciascun carattere con punti di codice intero, che consente 4 byte per carattere = 32 bit per coprire il 20 di cui abbiamo bisogno per unicode, con qualche spreco. Perché non esattamente 20 bit? Perché le cose sono più veloci quando sono allineate a byte. Alcuni linguaggi come Python < = 2 e Java rappresentano caratteri che utilizzano una codifica UTF-16, il che significa che devono utilizzare coppie surrogate per rappresentare unicode esteso (non BMP). In entrambi i casi è ancora massimo 4 byte.

risposta se andare UTF-8 -> codifica nativa: 4 byte

Quindi, conclusione finale, 4 è la risposta più comune a destra, quindi abbiamo ottenuto nel modo giusto. Ma in certi contesti dovresti stare attento. Ad esempio, non aspettarti di poter rappresentare qualsiasi cosa tu legga da un flusso UTF-8 in un massimo di 4 byte. Se non è unicode, potrebbero essere necessari fino a 6 byte.

+1

"questa è ancora la specifica attuale e corretta, per wikipedia" - non più. Poco dopo aver scritto questo (2 aprile modifica), l'articolo UTF-8 di Wikipedia è stato modificato per chiarire che la versione a 6 ottetti non fa parte delle specifiche UTF-8 correnti (2003). –

+0

"Ma, in Java <= v7, si parla di un massimo di 3 byte per rappresentare unicode con UTF-8? Questo perché la specifica unicode originale definiva solo il piano multi-lingua di base" - Questo è probabilmente il motivo originale, ma non è tutta la storia. Java usa "UTF-8 modificato" e una delle modifiche è che "usa il proprio formato due volte tre byte" anziché "il formato a quattro byte dello standard UTF-8" (le loro parole). –

+0

Non ci sono codepoints allocati sopra il limite 10FFFF (poco più di un milione) e molte implementazioni UTF8 non hanno mai implementato sequenze più lunghe di 4 byte (e alcuni solo 3, ad esempio MySQL) quindi considererei sicuro limitare a 4 byte per punto di codice anche quando si considera la compatibilità con le implementazioni precedenti. Dovresti solo assicurarti di scartare qualsiasi cosa invalida mentre entri. Nota che la raccomandazione di Matiu di allocare dopo aver calcolato la lunghezza esatta del byte è buona se possibile. – thomasrutter

Problemi correlati