iconv menghasilkan UTF-16 dengan BOM

11

Terinspirasi oleh pertanyaan ini , dapatkah saya menggunakan iconvperintah untuk menghasilkan output UTF-16 dengan BOM dan dengan endianness yang ditentukan?

The iconvperintah bertobat teks dari satu pengkodean ke yang lain.

Sebagai contoh:

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

menghasilkan representasi UTF-16 dari "hello\n".

File UTF-16 sering, tetapi tidak selalu, mulai dengan Byte Order Mark (BOM), yang merupakan pengodean 2-byte dari karakter Unicode U+FEFF. Anda dapat menentukan endianness file UTF-16 dengan BOM dengan memeriksa apakah dua byte pertama adalah FE FFatau FF FE.

The iconvperintah memiliki beberapa pilihan untuk menghasilkan UTF-16 keluaran:

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

Perintah ini:

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

menghasilkan big-endian UTF-16 tanpa BOM ; tampaknya menganggap bahwa jika Anda menentukan endianness, Anda tidak perlu menunjukkannya dalam output. Demikian pula, utf-16lemenghasilkan little-endian UTF-16 tanpa BOM.

Ini:

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

menghasilkan (pada sistem x86 Ubuntu saya) little-endian UTF-16 dengan BOM - tetapi saya telah melihat laporan dari perintah yang sama yang menghasilkan big-endian UTF-16 dengan BOM, bahkan pada sistem little-endian.

Saya selalu dapat menggunakan utf-16beatau utf-16ledan menambahkan BOM secara manual, tetapi saya sedang mencari solusi yang hanya menggunakan iconvperintah.

Solusi lain, jika Anda tahu apa yang -t utf-16dihasilkan endianness , adalah:

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

Apa yang saya ingin seperti penggunaan adalah sesuatu seperti:

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

tetapi iconvtidak mendukung itu.

EDIT:

Dapatkah seseorang dengan akses ke sistem Mac OSX x86 memposting komentar yang menunjukkan (copy-and-paste) output dari perintah berikut?

echo hello | iconv -f ascii -t utf-16 | od -x
Keith Thompson
sumber
1
BOM mengurangi portabilitas data tetapi Anda dapat menambahkannya dengan cara ini
RedGrittyBrick
@RedGrittyBrick: Bagaimana cara mengurangi portabilitas (khusus untuk UtF-16)? Saya tahu saya dapat menghasilkan BOM secara terbuka; Saya mencari cara untuk melakukannya hanya menggunakan iconv- dan bertanya-tanya mengapa -t utf-16tampaknya meninggalkan endianness tidak ditentukan.
Keith Thompson
Saya kira iconv mengasumsikan pemesanan byte platform saat ini jika Anda tidak menentukannya secara eksplisit. Pada beberapa platform selain windows, beberapa alat pengolah teks tidak mengharapkan BOM dan juga melakukan hal yang salah. Contohnya mungkin ketika menggabungkan file teks, atau menggunakan templat berbasis file untuk membuat konten. "Untuk rangkaian karakter yang terdaftar IANA UTF-16BE dan UTF-16LE, tanda urutan byte tidak boleh digunakan karena nama-nama rangkaian karakter ini telah menentukan urutan byte"
RedGrittyBrick
Pertanyaan ini menunjukkan iconv -f UTF-8 -t UTF-16, dijalankan pada sistem little-endian (MacOS), menghasilkan UTF-16 big-endian dengan BOM, yang tampaknya sangat aneh.
Keith Thompson

Jawaban:

9

Tidak , jika Anda menentukan pemesanan byte, iconvtidak memasukkan BOM.

Ini dari The Unicode Consortium

T: Bagaimana saya harus berurusan dengan BOM?

A: Berikut adalah beberapa panduan untuk diikuti:

  1. Protokol tertentu (misalnya, konvensi Microsoft untuk file .txt) mungkin memerlukan penggunaan BOM pada aliran data Unicode tertentu, seperti file. Saat Anda perlu menyesuaikan diri dengan protokol semacam itu, gunakan BOM.
  2. Beberapa protokol memungkinkan BOM opsional dalam kasus teks yang tidak ditandai. Dalam kasus itu,
    • Di mana aliran data teks dikenal sebagai teks biasa, tetapi dari pengkodean yang tidak diketahui, BOM dapat digunakan sebagai tanda tangan. Jika tidak ada BOM, pengodeannya bisa apa saja.
    • Di mana aliran data teks dikenal sebagai teks Unicode biasa (tapi bukan yang endian), maka BOM dapat digunakan sebagai tanda tangan. Jika tidak ada BOM, teks harus ditafsirkan sebagai big-endian.
  3. Beberapa protokol berorientasi byte mengharapkan karakter ASCII di awal file. Jika UTF-8 digunakan dengan protokol-protokol ini, penggunaan BOM sebagai tanda tangan formulir pengkodean harus dihindari.
  4. Jika jenis aliran data yang tepat diketahui (mis. Unicode big-endian atau Unicode little-endian), BOM tidak boleh digunakan. Secara khusus, setiap kali aliran data dinyatakan sebagai UTF-16BE, UTF-16LE, UTF-32BE atau UTF-32LE, BOM tidak boleh digunakan.

(penekanan saya)

Saya berharap iconvberusaha setia pada yang terakhir dari pedoman ini.


Memperbarui.

Penyimpangan

Menurutku:

  1. Opsi untuk menentukan BOM tentu akan menjadi fitur tambahan yang berguna untuk ikonv.

  2. Sebuah file UTF-16LE tanpa BOM adalah dapat digunakan di Windows, meskipun dengan upaya tambahan kadang-kadang. Misalnya, dialog Buka File Notepad memungkinkan Anda untuk memilih "Unicode" yang merupakan nama Microsoft untuk "UTF-16LE" dan (tidak mengejutkan) tampaknya berfungsi pada file tanpa BOM.

  3. Saya dapat membuka file uji UTF-16LE (tanpa BOM) atau file uji UTF-8 (tanpa BOM) di Windows Notepad (XP) dengan cara biasa, misalnya dengan mengklik dua kali nama file di explorer. Bagi saya itu sepertinya bermanfaat. Saya sadar bahwa terkadang Windows akan menebak penyandian dengan salah - Dalam hal ini Anda harus memberi tahu Notepad penyandian saat membuka file. Ketidaknyamanan ini berarti termasuk BOM lebih disukai untuk file teks yang dimaksudkan untuk digunakan pada Windows.

  4. Jika aplikasi tertentu tidak akan bekerja dengan apa pun selain file UTF-16LE dengan BOM, maka saya setuju bahwa file UTF-16LE tanpa BOM tidak dapat digunakan untuk aplikasi spesifik itu.

  5. Saya menduga bahwa jika Anda dapat membuat semuanya berfungsi dengan UTF-8 (tanpa BOM), itu adalah solusi terbaik dalam jangka panjang.

Namun jawaban untuk pertanyaan " dapatkah saya menggunakan perintah iconv untuk menghasilkan keluaran UTF-16 dengan BOM dan dengan endianness yang ditentukan " saat ini " Tidak ".

RedGrittyBrick
sumber
1
Dan bagaimana dengan pedoman pertama, A.1? Jika saya ingin membuat file teks Unicode yang dapat digunakan pada sistem Windows x86, itu harus berupa file UTF16 little-endian dengan BOM .
Keith Thompson
@KeithThompson: Sistem harus menerima baik UTF16LE dan UTF16BE. Setidaknya Windows Notepad menerima keduanya, ketika menyangkut .txt- selama file tersebut memiliki BOM.
user1686
@KeithThompson: Saya setuju bahwa pedoman 1 harus diprioritaskan, namun iconv tidak memberikan cara bagi Anda untuk menentukan BOM. Jawaban atas pertanyaan awal Anda hanyalah "Tidak".
RedGrittyBrick
Bukan jawaban yang saya harapkan, tetapi jawaban, dan jawaban yang menyeluruh!
Keith Thompson
2
Jawaban ini membantu saya - membantu saya belajar mengapa saya kacau. Program Windows standar untuk mengekspor / mengimpor dari registri, C:\Windows\System32\reg.exemengekspor UTF-16 LE WITH BOM dan hanya akan membaca UTF-16 LE WITH BOM - tidak akan membaca UTF-16 LE tanpa BOM dan tidak akan membaca UTF-16 BE with BOM - dengan kata lain, itu menuntut BOM saat membaca tetapi sebaiknya itu yang benar! (Untungnya, terbaca UTF-8.)
davidbak