6

Sembra che ci sia un'ambiguità tra i segni di ordine dei byte utilizzati per UTF16-LE e UTF-32LE. In particolare, si consideri un file che contiene i seguenti 8 byte:BOM Unicode per UTF-16LE rispetto a UTF32-LE

FF FE 00 00 00 00 00 00 

Come posso dire se questo file contiene:

  1. L'UTF16-LE BOM (FF FE) seguito da 3 caratteri nulli; oppure
  2. La BOM UTF32-LE (FF FE 00 00) seguita da un carattere nullo?

Le BOM Unicode sono descritte qui: http://unicode.org/faq/utf_bom.html#bom4 ma non si discute di questa ambiguità. Mi sto perdendo qualcosa?

risposta

10

Come suggerisce il nome, la distinta materiali indica solo l'ordine byte, non la codifica. È necessario sapere quale sia la codifica per prima, quindi è possibile utilizzare il BOM per determinare se i byte meno o più significativi sono i primi per le sequenze multibyte.

Un fortunato effetto collaterale della distinta base è che talvolta è possibile utilizzarlo anche per indovinare la codifica se non lo si conosce, ma non è quello per cui è stato progettato e non può sostituire l'invio della codifica corretta informazione.

10

Non è ambiguo. FF FE è per UTF-16LE e FF FE 00 00 indica UTF-32LE. Non c'è motivo di pensare che FF FE 00 00 sia probabilmente UTF-16LE perché le UTF sono state progettate per il testo e gli utenti non devono utilizzare caratteri NUL nel testo. Dopo tutto, quando è stata l'ultima volta che hai aperto un editor esadecimale e inserito alcuni byte di 00 in un documento di testo?^_^

+4

Il carattere null può essere parte di un protocollo di ordine superiore codificato nel testo. Unicode non si preoccupa realmente di quali punti di codice vengono usati nel testo e U + 0000 è valido come U + 0041. – Joey

+2

Leggendo un protocollo di ordine superiore, questa teoria è in conflitto con l'impostazione della domanda in cui la codifica deve essere indovinata. Se stai leggendo un protocollo, non indovinerai la codifica. – u0b34a0f6ae

+1

Per dirla in un altro modo, non è * impossibile * avere un U + 0000 all'inizio di un file, ma è * estremamente raro *. Se questa è una possibilità per i dati che stai leggendo, non dovresti fare affidamento su una distinta base per il rilevamento del formato. –

1

Ho avuto lo stesso problema come Edward. Sono d'accordo con Dustin, in genere non si useranno caratteri null nei file di testo.

Tuttavia, ho creato un file che contiene tutti i caratteri Unicode. Ho usato per la prima volta la codifica utf-32le, poi una codifica utf-32be, una codifica utf-16le e utf-16be oltre a una codifica utf-8.

Durante il tentativo di ricodificare i file in utf-8, volevo confrontare il risultato con il file utf-8 già esistente. Poiché il primo carattere nei miei file dopo il BOM è il carattere null, non sono riuscito a rilevare il file con BOM utf-16le, si è mostrato come BOM utf-32le, poiché i byte sono apparsi esattamente come descritto da Edward. Il primo carattere dopo il BOM FFFE è 0000, ma il rilevamento BOM ha trovato un BOM FFFE0000 e così, ha rilevato utf-32le invece di utf-16le per cui il mio primo 0000-personaggio è stato rubato e preso come parte del BOM.

Quindi non si dovrebbe mai usare un carattere null come primo carattere di un file codificato con utf-16 little endian, perché renderà ambigue le utf-16le e utf-32le BOM.

Per risolvere il mio problema, scambierò il primo e il secondo carattere. :-)

+0

Se ci si affida a una sola distinta componenti per rilevare la codifica, è necessario esaminare più byte rispetto al distinta base per risolvere l'ambiguità UTF-16/32. Prima controlla UTF-16LE e, se rilevato, controlla se i successivi N * 2 byte sono UTF-16LE validi, dove N è un numero ragionevole. Se non è UTF-16LE valido, ricominciare e assumere UTF-32LE. U + 0000 dovrebbe essere l'unico codepoint ambiguo e non dovrebbero esserci molti null all'inizio del file. A un certo punto, ci deve essere un taglio, e se non è ancora possibile risolvere l'ambiguità a quel punto, chiedere all'utente, o fallire l'elaborazione con un errore. –

+0

Il che significa che se si rileva una distinta base utf-32le, è necessario innanzitutto verificare se si tratta di una distinta base utf-16le con U + 0000 dopo il punto di codice. Se ci sono molte parole, questo potrebbe aiutare, probabilmente anche a cercare dei surrogati. Ma se ci sono solo parole di vista, questo può essere difficile. Ma sono d'accordo, quando controlli i codepoint validi di utf-32, possibilmente troverai dei codepoints oltre il massimo 0x10FFFF se è veramente un file codificato utf-16. In ogni caso dovremmo raccomandare di posizionare sempre un altro punto di codice diverso da U + 0000 come primo codepoint all'interno di un file codificato utf-16le. – brighty