iconv genera UTF-16 con DBA


11

Ispirato da questa domanda , posso usare il iconvcomando per generare output UTF-16 con una distinta base e con endianness specificato?

Il iconvcomando converte il testo da una codifica a un'altra.

Per esempio:

echo hello | iconv -f ascii -t utf-16

genera una rappresentazione UTF-16 di "hello\n".

I file UTF-16 spesso, ma non sempre, iniziano con un Byte Order Mark (BOM), che è una codifica a 2 byte del carattere Unicode U+FEFF. È possibile determinare l'endianità di un file UTF-16 con BOM controllando se i primi due byte sono FE FFo FF FE.

Il iconvcomando ha diverse opzioni per generare output UTF-16:

$ iconv --list | grep -i utf-16
UTF-16//
UTF-16BE//
UTF-16LE//

Questo comando:

echo hello | iconv -f ascii -t utf-16be

genera UTF-16 big-endian senza BOM ; sembra supporre che se si specifica l'endianness, non è necessario indicarlo nell'output. Allo stesso modo, utf-16legenera UTF-16 little-endian senza BOM.

Questo:

echo hello | iconv -f ascii -t utf-16

genera (sul mio sistema Ubuntu x86) UTF-16 little-endian con una BOM - ma ho visto un rapporto di un comando simile che genera UTF-16 big-endian con una BOM, anche su un sistema little-endian.

Posso sempre utilizzare utf-16beo utf-16leanteporre manualmente la distinta componenti, ma sto cercando una soluzione che utilizza solo il iconvcomando.

Un'altra soluzione alternativa, se sai cosa -t utf-16genera endianness , è:

echo hello | iconv -f ascii -t utf-16 | dd conv=swab 2>/dev/null

Quello che mi piace da utilizzare è qualcosa di simile:

iconv -f ascii -t utf-16bebom # big-endian with BOM
iconv -f ascii -t utf-16lebom # little-endian with BOM

ma iconvnon lo supporta.

MODIFICARE :

Qualcuno con accesso a un sistema Mac OSX x86 può pubblicare un commento che mostra l'output (copia e incolla) del seguente comando?

echo hello | iconv -f ascii -t utf-16 | od -x

1
Una DBA riduce la portabilità dei dati ma è possibile aggiungerla in questo modo
RedGrittyBrick

@RedGrittyBrick: come riduce la portabilità (in particolare per UtF-16)? So di poter generare la distinta componenti in modo ezplicit; Sto cercando un modo per farlo semplicemente usando iconv- e mi chiedo perché -t utf-16sembra lasciare l'endianità non specificata.
Keith Thompson,

Immagino che iconv ipotizzi l'attuale ordinamento di byte della piattaforma se non lo specifichi esplicitamente. Su alcune piattaforme diverse da Windows, alcuni strumenti di elaborazione del testo non prevedono BOM e quindi fanno la cosa sbagliata. Un esempio potrebbe essere quando si concatenano file di testo o si utilizzano modelli basati su file per costruire contenuti. "Per i set di caratteri registrati IANA UTF-16BE e UTF-16LE, un contrassegno di ordine di byte non deve essere utilizzato perché i nomi di questi set di caratteri determinano già l'ordine di byte"
RedGrittyBrick il

Questa domanda mostra iconv -f UTF-8 -t UTF-16, funziona su un sistema little-endian (MacOS), generando UTF-16 big-endian con una distinta base, che sembra molto strano.
Keith Thompson,

Risposte:


9

No , se si specifica l'ordine dei byte, iconvnon viene inserita una DBA.

Questo proviene dal consorzio Unicode

D: Come dovrei gestire le distinte base?

A: Ecco alcune linee guida da seguire:

  1. Un protocollo particolare (ad es. Convenzioni Microsoft per i file .txt) potrebbe richiedere l'uso della distinta base su determinati flussi di dati Unicode, come i file. Quando è necessario conformarsi a tale protocollo, utilizzare una DBA.
  2. Alcuni protocolli consentono distinte componenti opzionali nel caso di testo senza tag. In questi casi,
    • Laddove un flusso di dati di testo sia noto come testo semplice, ma con codifica sconosciuta, la distinta componenti può essere utilizzata come firma. Se non è presente alcuna DBA, la codifica potrebbe essere qualsiasi cosa.
    • Laddove un flusso di dati di testo è noto per essere un semplice testo Unicode (ma non quale endian), allora la distinta base può essere utilizzata come firma. Se non vi è alcuna distinta base, il testo deve essere interpretato come big-endian.
  3. Alcuni protocolli orientati al byte prevedono caratteri ASCII all'inizio di un file. Se UTF-8 viene utilizzato con questi protocolli, è necessario evitare l'uso della DBA come firma del modulo di codifica.
  4. Laddove sia noto il tipo preciso del flusso di dati (ad esempio Unicode big-endian o Unicode little-endian), la distinta componenti non deve essere utilizzata. In particolare, ogni volta che un flusso di dati viene dichiarato UTF-16BE, UTF-16LE, UTF-32BE o UTF-32LE non è necessario utilizzare una distinta base .

(la mia enfasi)

Mi aspetto che iconvstia tentando di essere fedele all'ultimo di questi orientamenti.


Aggiornare.

Una digressione

Secondo me:

  1. Un'opzione per specificare una DBA sarebbe sicuramente un'utile funzione aggiuntiva per iconv.

  2. Un file UTF-16LE senza BOM è utilizzabile in Windows, anche se a volte con uno sforzo aggiuntivo. Ad esempio, la finestra di dialogo Apri file di Blocco note consente di selezionare "Unicode", che è il nome di Microsoft per "UTF-16LE" e (non a caso) sembra funzionare su file senza una distinta base.

  3. Posso aprire un file di test UTF-16LE (senza BOM) o un file di test UTF-8 (senza BOM) nel Blocco note di Windows (XP) nel solito modo, ad esempio facendo doppio clic sul nome del file in Explorer. Mi sembra utilizzabile. Sono consapevole che a volte Windows indovina la codifica in modo errato - nel qual caso devi dire a Notepad la codifica quando apri il file. Questo inconveniente significa che includere una DBA è preferibile per i file di testo destinati all'uso su Windows.

  4. Se un'applicazione specifica non funzionerà con qualcosa di diverso da un file UTF-16LE con BOM, allora sarei d'accordo che un file UTF-16LE senza BOM non sia utilizzabile per quella specifica applicazione.

  5. Sospetto che se riesci a far funzionare tutto con UTF-8 (senza distinta base), questa è la soluzione migliore a lungo termine.

Tuttavia, la risposta alla domanda " posso usare il comando iconv per generare output UTF-16 con una distinta base e con endianness specificato " è attualmente " No ".


1
E la prima linea guida, A.1? Se f voglio generare un file di testo Unicode utilizzabile su un sistema Windows x86, dovrebbe essere un file UTF16 little-endian con una distinta base .
Keith Thompson,

@KeithThompson: i sistemi dovrebbero accettare sia UTF16LE che UTF16BE. Almeno Windows Notepad accetta entrambi, quando si tratta di .txt- purché il file abbia una DBA.
user1686

@KeithThompson: sono d'accordo che la linea guida 1 dovrebbe avere la priorità, tuttavia iconv non fornisce un modo per specificare una DBA. La risposta alla tua domanda originale è semplicemente "No".
RedGrittyBrick il

Non la risposta che speravo, ma una risposta e completa!
Keith Thompson,

2
Questa risposta mi ha aiutato, mi ha aiutato a capire perché sono stato fregato. Il programma Windows standard per esportare / importare dal registro, C:\Windows\System32\reg.exeesporta UTF-16 LE WITH BOM e leggerà solo UTF-16 LE WITH BOM - non leggerà UTF-16 LE senza BOM e non leggerà UTF-16 BE con BOM - in altre parole, richiede la distinta base durante la lettura, ma è meglio che sia quella giusta! (Fortunatamente, legge UTF-8.)
davidbak,
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.