Saya akan bertanya apa yang mungkin merupakan pertanyaan yang cukup kontroversial: "Haruskah salah satu pengkodean paling populer, UTF-16, dianggap berbahaya?"
Mengapa saya menanyakan pertanyaan ini?
Berapa banyak programmer yang menyadari fakta bahwa UTF-16 sebenarnya adalah penyandian panjang variabel? Maksud saya, ada poin kode yang, diwakili sebagai pasangan pengganti, mengambil lebih dari satu elemen.
Aku tahu; banyak aplikasi, kerangka kerja dan API menggunakan UTF-16, seperti Java's String, C #'s String, Win32 APIs, pustaka Qt GUI, pustaka ICU Unicode, dll. Namun, dengan semua itu, ada banyak bug dasar dalam pemrosesan karakter keluar dari BMP (karakter yang harus dikodekan menggunakan dua elemen UTF-16).
Misalnya, coba edit salah satu karakter ini:
- 𝄞 ( U + 1D11E ) SIMBOL MUSIK G CLEF
- 𝕥 ( U + 1D565 ) MATEMATIK GANDA-STRUCK KECIL T
- 𝟶 ( U + 1D7F6 ) NOL DIGITAL MATEMATIKA NOL
- 𠂊 ( U + 2008A ) Karakter Han
Anda mungkin kehilangan beberapa, tergantung pada font apa yang telah Anda instal. Semua karakter ini berada di luar BMP (Basic Multilingual Plane). Jika Anda tidak dapat melihat karakter ini, Anda juga dapat mencoba melihatnya di referensi Karakter Unicode .
Misalnya, coba buat nama file di Windows yang menyertakan karakter ini; coba hapus karakter-karakter ini dengan "backspace" untuk melihat bagaimana mereka berperilaku dalam aplikasi yang berbeda yang menggunakan UTF-16. Saya melakukan beberapa tes dan hasilnya sangat buruk:
- Opera bermasalah dengan pengeditannya (perlu hapus 2 penekanan pada backspace)
- Notepad tidak dapat mengatasinya dengan benar (perlu hapus 2 penekanan pada backspace)
- Pengeditan nama file dalam dialog Window in broken (perlu hapus 2 penekanan pada backspace)
- Semua aplikasi QT3 tidak dapat mengatasinya - tampilkan dua kotak kosong bukan satu simbol.
- Python menyandikan karakter seperti itu secara salah ketika digunakan secara langsung
u'X'!=unicode('X','utf-16')
pada beberapa platform ketika X dalam karakter di luar BMP. - Python 2.5 unicodedata gagal mendapatkan properti pada karakter seperti itu ketika python dikompilasi dengan string Unicode UTF-16.
- StackOverflow tampaknya menghapus karakter ini dari teks jika diedit langsung sebagai karakter Unicode (karakter ini ditampilkan menggunakan HTML Unicode escapes).
- WinForms TextBox dapat menghasilkan string yang tidak valid ketika dibatasi dengan MaxLength.
Tampaknya bug seperti itu sangat mudah ditemukan di banyak aplikasi yang menggunakan UTF-16.
Jadi ... Apakah Anda berpikir bahwa UTF-16 harus dianggap berbahaya?
Jawaban:
Opini: Ya, UTF-16 harus dianggap berbahaya . Alasan mengapa hal itu ada adalah karena beberapa waktu lalu dulu ada kepercayaan sesat bahwa widechar akan menjadi seperti apa UCS-4 sekarang.
Meskipun "anglo-sentralisme" dari UTF-8, itu harus dianggap sebagai satu-satunya penyandian teks yang bermanfaat. Orang dapat berargumen bahwa kode sumber program, halaman web dan file XML, nama file OS dan antarmuka teks komputer-ke-komputer lainnya seharusnya tidak pernah ada. Tetapi ketika mereka melakukannya, teks tidak hanya untuk pembaca manusia.
Di sisi lain, overhead UTF-8 adalah harga yang murah untuk dibayar sementara itu memiliki keuntungan yang signifikan. Keuntungan seperti kompatibilitas dengan kode tidak disadari yang baru saja melewati string
char*
. Ini adalah sesuatu yang bagus. Ada beberapa karakter berguna yang SHORTER di UTF-16 daripada di UTF-8.Saya percaya bahwa semua pengkodean lainnya akan mati pada akhirnya. Ini melibatkan bahwa MS-Windows, Java, ICU, python berhenti menggunakannya sebagai favorit mereka. Setelah penelitian dan diskusi yang panjang, konvensi pengembangan di perusahaan saya melarang menggunakan UTF-16 di mana pun kecuali panggilan OS API, dan ini terlepas dari pentingnya kinerja dalam aplikasi kami dan fakta bahwa kami menggunakan Windows. Fungsi konversi dikembangkan untuk mengonversi UTF8 yang selalu diasumsikan
std::string
menjadi UTF-16 asli, yang Windows sendiri tidak mendukung dengan benar .Untuk orang-orang yang mengatakan " gunakan apa yang dibutuhkan di tempat yang dibutuhkan ", saya katakan: ada keuntungan besar untuk menggunakan pengkodean yang sama di mana-mana, dan saya tidak melihat alasan yang cukup untuk melakukan sebaliknya. Secara khusus, saya pikir menambahkan
wchar_t
ke C ++ adalah kesalahan, dan begitu pula penambahan Unicode ke C ++ 0x. Apa yang harus diminta dari implementasi STL adalah bahwa setiapstd::string
atauchar*
parameter akan dianggap kompatibel dengan unicode.Saya juga menentang pendekatan " gunakan apa yang Anda inginkan ". Saya tidak melihat alasan untuk kebebasan seperti itu. Ada cukup banyak kebingungan pada masalah teks, sehingga semua perangkat lunak yang rusak ini. Setelah mengatakan di atas, saya yakin bahwa programmer akhirnya harus mencapai konsensus tentang UTF-8 sebagai satu cara yang tepat. (Saya berasal dari negara yang tidak menggunakan bahasa Ascii dan dibesarkan di Windows, jadi saya yang terakhir diharapkan menyerang UTF-16 berdasarkan alasan agama).
Saya ingin berbagi informasi lebih lanjut tentang cara saya melakukan teks pada Windows, dan apa yang saya rekomendasikan kepada semua orang untuk diperiksa waktu kompilasi unicode, kemudahan penggunaan dan multi-platformness kode yang lebih baik. Saran ini sangat berbeda dari apa yang biasanya direkomendasikan sebagai cara yang tepat untuk menggunakan Unicode di windows. Namun, penelitian mendalam dari rekomendasi ini menghasilkan kesimpulan yang sama. Jadi begini:
wchar_t
ataustd::wstring
di tempat lain selain titik yang berdekatan dengan API yang menerima UTF-16._T("")
atauL""
UTF-16 literal (Ini harus IMO dikeluarkan dari standar, sebagai bagian dari penghentian UTF-16)._UNICODE
konstanta, sepertiLPTSTR
atauCreateWindow()
._UNICODE
selalu didefinisikan, untuk menghindari memberikanchar*
string ke WinAPI dikompilasi secara diam-diamstd::strings
danchar*
di mana saja dalam program dianggap UTF-8 (jika tidak dikatakan sebaliknya)std::string
, meskipun Anda dapat meneruskan char * atau string literal keconvert(const std::string &)
.hanya menggunakan fungsi Win32 yang menerima widechars (
LPWSTR
). Tidak pernah mereka yang menerimaLPTSTR
atauLPSTR
. Lewati parameter dengan cara ini:(Kebijakan tersebut menggunakan fungsi konversi di bawah.)
Dengan string MFC:
Bekerja dengan file, nama file, dan aliran pada Windows:
std::string
atauconst char*
mengajukan argumen nama kepadafstream
keluarga. MSVC STL tidak mendukung argumen UTF-8, tetapi memiliki ekstensi non-standar yang harus digunakan sebagai berikut:Konversi
std::string
argumen menjadistd::wstring
denganUtils::Convert
:Kita harus menghapus konversi secara manual, ketika sikap MSVC
fstream
berubah.fstream
kasus / penelitian 4215 unicode untuk informasi lebih lanjut.fopen()
karena alasan RAII / OOD. Jika perlu, gunakan_wfopen()
dan WinAPI konvensi di atas.sumber
Codepoints unicode bukan karakter! Kadang-kadang mereka bahkan bukan mesin terbang (bentuk visual).
Beberapa contoh:
Satu-satunya cara untuk mendapatkan pengeditan Unicode yang benar adalah dengan menggunakan perpustakaan yang ditulis oleh seorang ahli , atau menjadi seorang ahli dan menulis sendiri. Jika Anda hanya menghitung codepoint, Anda hidup dalam keadaan dosa.
sumber
Ada aturan sederhana tentang apa yang Unicode Transformation Form (UTF) gunakan: - utf-8 untuk penyimpanan dan komunikasi - utf-16 untuk pemrosesan data - Anda bisa menggunakan utf-32 jika sebagian besar platform API yang Anda gunakan adalah utf-32 (umum di dunia UNIX).
Sebagian besar sistem saat ini menggunakan utf-16 (Windows, Mac OS, Java, .NET, ICU, Qt). Lihat juga dokumen ini: http://unicode.org/notes/tn12/
Kembali ke "UTF-16 sebagai berbahaya", saya akan mengatakan: pasti tidak.
Orang-orang yang takut akan pengganti (berpikir bahwa mereka mengubah Unicode menjadi pengkodean variabel-panjang) tidak memahami kompleksitas (cara yang lebih besar) lainnya yang membuat pemetaan antara karakter dan titik kode Unicode sangat kompleks: menggabungkan karakter, pengikat, pemilih pemilih , mengontrol karakter, dll.
Baca seri ini di sini http://www.siao2.com/2009/06/29/9800913.aspx dan lihat bagaimana UTF-16 menjadi masalah yang mudah.
sumber
equalsIgnoreCase
(juga yang lain di kelas string) yang tidak akan pernah ada jika Java digunakan baik UTF-8 atau UTF-32. Ada jutaan bom tidur dalam kode apa pun yang menggunakan UTF-16, dan saya muak dan bosan dengan itu. UTF-16 adalah cacar ganas yang mengganggu perangkat lunak kami dengan bug berbahaya selamanya. Ini jelas berbahaya, dan harus ditinggalkan dan dilarang..Substring(1)
dalam .NET adalah contoh sepele dari sesuatu yang memecah dukungan untuk semua Unicode non-BMP. Segala sesuatu yang menggunakan UTF-16 memiliki masalah ini; terlalu mudah untuk memperlakukannya sebagai pengodean dengan lebar tetap, dan Anda melihat masalah terlalu jarang. Itu membuatnya menjadi pengkodean yang aktif berbahaya jika Anda ingin mendukung Unicode.Ya, tentu saja.
Mengapa? Itu ada hubungannya dengan menggunakan kode .
Jika Anda melihat statistik penggunaan codepoint ini pada sebuah corpus besar oleh Tom Christiansen, Anda akan melihat bahwa codepoint BMP trans-8bit digunakan beberapa pesanan jika besarnya lebih dari pada codepoint non-BMP:
Ambil diktum TDD: "Kode yang belum diuji adalah kode yang rusak", dan ulangi kata itu sebagai "kode yang tidak dieksekusi adalah kode yang rusak", dan pikirkan seberapa sering programmer harus berurusan dengan titik-titik kode non-BMP.
Bug yang terkait dengan tidak berurusan dengan UTF-16 sebagai pengodean lebar variabel lebih mungkin tidak diketahui daripada bug yang setara di UTF-8 . Beberapa bahasa pemrograman masih tidak menjamin untuk memberi Anda UTF-16, bukan UCS-2, dan beberapa bahasa pemrograman tingkat tinggi menawarkan akses ke unit kode alih-alih kode-poin (bahkan C seharusnya memberi Anda akses ke codepoints jika Anda gunakan
wchar_t
, terlepas dari apa yang mungkin dilakukan beberapa platform).sumber
Saya akan menyarankan bahwa berpikir UTF-16 mungkin dianggap berbahaya mengatakan bahwa Anda perlu mendapatkan pemahaman yang lebih besar tentang unicode .
Karena saya telah kalah memilih untuk menyampaikan pendapat saya tentang pertanyaan subyektif, izinkan saya menguraikan. Apa sebenarnya yang mengganggu Anda tentang UTF-16? Apakah Anda lebih suka jika semuanya dikodekan dalam UTF-8? UTF-7? Atau bagaimana dengan UCS-4? Tentu saja aplikasi tertentu tidak dirancang untuk menangani kode karakter setiap orang di luar sana - tetapi mereka diperlukan, terutama dalam domain informasi global saat ini, untuk komunikasi antar batas internasional.
Tapi sungguh, jika Anda merasa UTF-16 harus dianggap berbahaya karena membingungkan atau dapat diimplementasikan secara tidak benar (unicode tentu saja bisa), lalu metode pengkodean karakter apa yang dianggap tidak berbahaya?
EDIT: Untuk memperjelas: Mengapa menganggap implementasi yang tidak tepat dari suatu standar mencerminkan kualitas dari standar itu sendiri? Seperti yang telah dicatat oleh orang lain, hanya karena aplikasi menggunakan alat secara tidak tepat, tidak berarti bahwa alat itu sendiri rusak. Jika itu masalahnya, kita mungkin bisa mengatakan hal-hal seperti "kata kunci var dianggap berbahaya", atau "threading dianggap berbahaya". Saya pikir pertanyaannya membingungkan kualitas dan sifat standar dengan kesulitan yang dimiliki banyak programmer dalam menerapkan dan menggunakannya dengan benar, yang saya rasa lebih berasal dari kurangnya pemahaman mereka tentang bagaimana unicode bekerja, daripada unicode itu sendiri.
sumber
Tidak ada yang salah dengan pengkodean Utf-16. Tetapi bahasa yang memperlakukan unit 16-bit sebagai karakter mungkin harus dianggap dirancang dengan buruk. Memiliki tipe bernama '
char
' yang tidak selalu mewakili karakter cukup membingungkan. Karena sebagian besar pengembang akan mengharapkan tipe char untuk mewakili titik kode atau karakter, banyak kode mungkin akan rusak ketika terkena karakter di luar BMP.Perhatikan bahwa meskipun menggunakan utf-32 tidak berarti bahwa setiap titik kode 32-bit akan selalu mewakili karakter. Karena menggabungkan karakter, karakter yang sebenarnya dapat terdiri dari beberapa titik kode. Unicode tidak pernah sepele.
BTW. Mungkin ada kelas bug yang sama dengan platform dan aplikasi yang mengharapkan karakter menjadi 8-bit, yang diberi makan Utf-8.
sumber
CodePoint
tipe, memegang satu titik kode (21 bit),CodeUnit
tipe, memegang unit kode tunggal (16 bit untuk UTF-16) dan suatuCharacter
tipe idealnya harus mendukung grapheme lengkap. Tapi itu membuatnya secara fungsional setara denganString
...Pilihan pribadi saya adalah selalu menggunakan UTF-8. Ini standar di Linux untuk hampir semuanya. Ini kompatibel dengan banyak aplikasi lawas. Ada overhead yang sangat minimal dalam hal ruang ekstra yang digunakan untuk karakter non-latin vs format UTF lainnya, dan ada penghematan yang signifikan dalam ruang untuk karakter latin. Di web, bahasa latin berkuasa, dan saya pikir mereka akan melakukannya di masa mendatang. Dan untuk mengatasi salah satu argumen utama dalam posting asli: hampir setiap programmer menyadari bahwa terkadang UTF-8 memiliki karakter multi-byte di dalamnya. Tidak semua orang berurusan dengan ini dengan benar, tetapi mereka biasanya sadar, yang lebih dari yang bisa dikatakan untuk UTF-16. Tapi, tentu saja, Anda harus memilih yang paling sesuai untuk aplikasi Anda. Itu sebabnya ada lebih dari satu.
sumber
Ya, ada pengkodean yang menggunakan simbol ukuran tetap. Maksud saya UTF-32. Tetapi 4 byte untuk setiap simbol terlalu banyak ruang terbuang, mengapa kita menggunakannya dalam situasi sehari-hari?
Menurut saya, sebagian besar masalah muncul dari kenyataan bahwa beberapa perangkat lunak berada di belakang standar Unicode, tetapi tidak cepat untuk memperbaiki situasi. Opera, Windows, Python, Qt - semuanya muncul sebelum UTF-16 dikenal luas atau bahkan muncul. Namun, saya dapat mengonfirmasi bahwa di Opera, Windows Explorer, dan Notepad tidak ada masalah dengan karakter di luar BMP lagi (setidaknya pada PC saya). Tapi bagaimanapun, jika program tidak mengenali pasangan pengganti, maka mereka tidak menggunakan UTF-16. Apa pun masalah yang timbul dari berurusan dengan program-program tersebut, mereka tidak ada hubungannya dengan UTF-16 itu sendiri.
Namun, saya berpikir bahwa masalah perangkat lunak lama dengan hanya dukungan BMP agak berlebihan. Karakter di luar BMP hanya ditemui dalam kasus dan wilayah yang sangat spesifik. Menurut FAQ resmi Unicode , "bahkan dalam teks Asia Timur, kejadian pasangan pengganti harus rata-rata kurang dari 1% dari semua penyimpanan teks rata-rata". Tentu saja, karakter di luar BMP tidak boleh diabaikan karena program tidak sesuai dengan Unicode, tetapi sebagian besar program tidak dimaksudkan untuk bekerja dengan teks yang mengandung karakter tersebut. Itu sebabnya jika mereka tidak mendukungnya, itu tidak menyenangkan, tetapi bukan bencana.
Sekarang mari kita pertimbangkan alternatifnya. Jika UTF-16 tidak ada, maka kami tidak akan memiliki pengkodean yang cocok untuk teks non-ASCII, dan semua perangkat lunak yang dibuat untuk UCS-2 harus sepenuhnya dirancang ulang untuk tetap sesuai dengan Unicode. Yang terakhir kemungkinan besar hanya akan memperlambat adopsi Unicode. Kami juga tidak akan dapat mempertahankan kompabilitas dengan teks dalam UCS-2 seperti UTF-8 dalam kaitannya dengan ASCII.
Sekarang, dengan mengesampingkan semua masalah warisan, apa argumen yang menentang pengkodean itu sendiri? Saya benar-benar ragu bahwa pengembang saat ini tidak tahu bahwa UTF-16 panjang variabel, ditulis di mana-mana yang dimulai dengan Wikipedia. UTF-16 jauh lebih sulit diurai daripada UTF-8, jika seseorang menunjukkan kompleksitas sebagai masalah yang mungkin terjadi. Juga salah untuk berpikir bahwa mudah untuk mengacaukan dengan menentukan panjang string hanya di UTF-16. Jika Anda menggunakan UTF-8 atau UTF-32, Anda masih harus menyadari bahwa satu titik kode Unicode tidak selalu berarti satu karakter. Selain itu, saya tidak berpikir ada sesuatu yang substansial terhadap penyandian.
Karena itu saya tidak berpikir bahwa pengkodean itu sendiri harus dianggap berbahaya. UTF-16 adalah kompromi antara kesederhanaan dan kekompakan, dan tidak ada salahnya menggunakan apa yang diperlukan di mana itu diperlukan . Dalam beberapa kasus Anda harus tetap kompatibel dengan ASCII dan Anda perlu UTF-8, dalam beberapa kasus Anda ingin bekerja dengan bekerja dengan ideograf Han dan menghemat ruang menggunakan UTF-16, dalam beberapa kasus Anda perlu representasi universal karakter menggunakan tanda tetap pengkodean panjang. Gunakan apa yang lebih tepat, lakukan saja dengan benar.
sumber
Bertahun-tahun Windows internasionalisasi bekerja terutama dalam bahasa-bahasa Asia Timur mungkin telah merusak saya, tetapi saya condong ke UTF-16 untuk representasi string internal-ke-program, dan UTF-8 untuk penyimpanan jaringan atau file dokumen seperti plaintext. UTF-16 biasanya dapat diproses lebih cepat di Windows, jadi itulah manfaat utama menggunakan UTF-16 di Windows.
Membuat lompatan ke UTF-16 secara dramatis meningkatkan kecukupan produk rata-rata yang menangani teks internasional. Hanya ada beberapa kasus sempit ketika pasangan pengganti perlu dipertimbangkan (penghapusan, penyisipan, dan pemecahan garis, pada dasarnya) dan sebagian besar kasing rata-rata adalah pass-through langsung. Dan tidak seperti pengkodean sebelumnya seperti varian JIS, UTF-16 membatasi pasangan pengganti untuk rentang yang sangat sempit, sehingga pemeriksaannya sangat cepat dan bekerja maju dan mundur.
Memang, ini kira-kira sama cepatnya dengan UTF-8 yang dikodekan dengan benar. Tetapi ada juga banyak aplikasi UTF-8 yang rusak yang secara salah mengkodekan pasangan pengganti sebagai dua urutan UTF-8. Jadi UTF-8 tidak menjamin keselamatan juga.
IE menangani pasangan pengganti dengan cukup baik sejak 2000 atau lebih, meskipun biasanya mengubah mereka dari halaman UTF-8 ke representasi UTF-16 internal; Saya cukup yakin Firefox telah melakukannya dengan benar juga, jadi saya tidak begitu peduli apa yang dilakukan Opera.
UTF-32 (alias UCS4) tidak ada gunanya untuk sebagian besar aplikasi karena ini sangat menuntut ruang, jadi ini cukup nonstarter.
sumber
UTF-8 jelas merupakan cara yang harus ditempuh, mungkin disertai dengan UTF-32 untuk penggunaan internal dalam algoritma yang memerlukan akses acak berkinerja tinggi (tetapi mengabaikan kombinasi karakter).
Baik UTF-16 dan UTF-32 (serta varian LE / BE mereka) mengalami masalah endianess, sehingga mereka tidak boleh digunakan secara eksternal.
sumber
UTF-16? pasti berbahaya. Hanya sebutir garam saya di sini, tetapi ada tiga penyandian teks yang dapat diterima dalam sebuah program:
integer codepoints ("CP"?): array bilangan bulat terbesar yang nyaman untuk bahasa dan platform pemrograman Anda (meluruh ke ASCII dalam batas resorpsi rendah). Seharusnya int32 pada komputer lama dan int64 pada apa pun dengan pengalamatan 64-bit.
Jelas antarmuka ke kode lama menggunakan pengkodean apa yang diperlukan untuk membuat kode lama berfungsi dengan benar.
sumber
U+10ffff
max akan keluar jendela ketika (tidak jika) mereka kehabisan codepoints. Yang mengatakan, menggunakan int32 pada sistem p64 untuk kecepatan mungkin aman, karena saya ragu mereka akan melebihiU+ffffffff
sebelum Anda dipaksa untuk menulis ulang kode Anda untuk sistem 128 bit sekitar 2050. (Itulah titik "gunakan int terbesar yang nyaman "sebagai kebalikan dari" terbesar yang tersedia "(yang mungkin int256 atau bignum atau sesuatu).)U+10FFFF
. Ini benar-benar adalah salah satu situasi ketika 21 bit sudah cukup untuk siapa pun.Unicode mendefinisikan poin kode hingga 0x10FFFF (1.114.112 kode), semua aplikasi yang berjalan di lingkungan multibahasa berurusan dengan string / nama file, dll. Harus menanganinya dengan benar.
Utf-16 : hanya mencakup 1.112.064 kode. Meskipun yang ada di akhir Unicode berasal dari pesawat 15-16 (Area Penggunaan Pribadi). Itu tidak dapat tumbuh lebih jauh di masa depan kecuali melanggar konsep Utf-16 .
Utf-8 : mencakup secara teoritis 2.216.757.376 kode. Rentang kode Unicode saat ini dapat diwakili oleh urutan maksimal 4 byte. Itu tidak menderita dengan masalah urutan byte , itu "kompatibel" dengan ascii.
Utf-32 : mencakup secara teoritis 2 ^ 32 = 4.294.967.296 kode. Saat ini tidak panjang variabel dikodekan dan mungkin tidak akan di masa depan.
Fakta-fakta itu jelas. Saya tidak mengerti menganjurkan penggunaan umum Utf-16 . Ini adalah variabel panjang yang disandikan (tidak dapat diakses oleh indeks), ia memiliki masalah untuk mencakup seluruh rentang Unicode bahkan saat ini, pesanan byte harus ditangani, dll. Saya tidak melihat keuntungan apa pun kecuali bahwa itu digunakan secara asli di Windows dan beberapa tempat lain. Meskipun saat menulis kode multi-platform, mungkin lebih baik menggunakan Utf-8 secara asli dan melakukan konversi hanya pada titik akhir dengan cara yang bergantung pada platform (seperti yang sudah disarankan). Ketika akses langsung dengan indeks diperlukan dan memori tidak menjadi masalah, Utf-32 harus digunakan.
Masalah utama adalah bahwa banyak programmer yang berurusan dengan Windows Unicode = Utf-16 bahkan tidak tahu atau mengabaikan fakta bahwa itu adalah panjang variabel yang dikodekan.
Cara biasanya di platform * nix cukup bagus, c string (char *) diartikan sebagai Utf-8 dikodekan, string c lebar (wchar_t *) diartikan sebagai Utf-32 .
sumber
Tambahkan ini ke daftar:
Sumber: Michael S. Kaplan Blog MSDN
sumber
Saya tidak perlu mengatakan bahwa UTF-16 berbahaya. Itu tidak elegan, tetapi melayani tujuan kompatibilitas mundur dengan UCS-2, seperti halnya GB18030 dengan GB2312, dan UTF-8 tidak dengan ASCII.
Tetapi membuat perubahan mendasar pada struktur Unicode di tengah aliran, setelah Microsoft dan Sun membangun API besar sekitar karakter 16-bit, berbahaya. Kegagalan untuk menyebarkan kesadaran akan perubahan itu lebih berbahaya.
sumber
UTF-16 adalah kompromi terbaik antara penanganan dan ruang dan itulah mengapa sebagian besar platform utama (Win32, Java, .NET) menggunakannya untuk representasi internal string.
sumber
Saya tidak pernah mengerti maksud UTF-16. Jika Anda menginginkan representasi paling hemat ruang, gunakan UTF-8. Jika Anda ingin dapat memperlakukan teks sebagai panjang tetap, gunakan UTF-32. Jika Anda tidak menginginkan keduanya, gunakan UTF-16. Lebih buruk lagi, karena semua karakter umum (bidang multibahasa dasar) dalam UTF-16 muat dalam satu titik kode, bug yang menganggap bahwa UTF-16 adalah fixed-length akan sulit ditemukan, sedangkan jika Anda mencoba melakukan ini dengan UTF-8, kode Anda akan gagal dengan cepat dan keras segera setelah Anda mencoba menginternasionalkan.
sumber
Karena saya belum bisa berkomentar, saya memposting ini sebagai jawaban, karena sepertinya saya tidak bisa menghubungi penulis dari
utf8everywhere.org
. Sayang sekali saya tidak secara otomatis mendapatkan hak istimewa komentar, karena saya memiliki cukup reputasi di stackexchanges lainnya.Ini dimaksudkan sebagai komentar pada Pendapat: Ya, UTF-16 harus dianggap sebagai jawaban yang berbahaya .
Satu koreksi kecil:
Untuk mencegah satu dari secara tidak sengaja melewatkan UTF-8
char*
ke versi ANSI-string fungsi Windows-API, orang harus mendefinisikanUNICODE
, bukan_UNICODE
._UNICODE
fungsi peta seperti_tcslen
untukwcslen
, tidakMessageBox
untukMessageBoxW
. Alih-alih,UNICODE
definisi tersebut mengatur yang terakhir. Sebagai bukti, ini dariWinUser.h
header MS Visual Studio 2005 :Paling tidak, kesalahan ini harus diperbaiki
utf8everywhere.org
.Sebuah sugesti:
Mungkin panduan ini harus berisi contoh penggunaan eksplisit dari versi Lebar-string dari struktur data, untuk membuatnya lebih mudah ketinggalan / lupakan. Menggunakan versi Lebar-string dari struktur data di atas menggunakan versi Lebar-fungsi fungsi membuatnya lebih kecil kemungkinannya bahwa seseorang secara tidak sengaja memanggil versi ANSI-string dari fungsi semacam itu.
Contoh dari contoh:
sumber
_UNICODE
masih ada di sana :(Seseorang mengatakan UCS4 dan UTF-32 sama. Tidak, tapi saya tahu apa yang Anda maksud. Salah satunya adalah pengkodean yang lain. Saya berharap mereka berpikir untuk menentukan endianness dari yang pertama sehingga kita tidak akan memiliki pertempuran endianess yang diperjuangkan di sini juga. Tidak bisakah mereka melihat kedatangan itu? Setidaknya UTF-8 adalah sama di mana-mana (kecuali seseorang mengikuti spesifikasi asli dengan 6-byte).
Jika Anda menggunakan UTF-16 Anda harus memasukkan penanganan untuk karakter multibyte. Anda tidak dapat pergi ke karakter Nth dengan mengindeks 2N ke dalam array byte. Anda harus berjalan, atau memiliki indeks karakter. Kalau tidak, Anda sudah menulis bug.
Draf spesifikasi C ++ saat ini mengatakan bahwa UTF-32 dan UTF-16 dapat memiliki varian little-endian, big-endian, dan tidak spesifik. Benarkah? Jika Unicode telah menetapkan bahwa setiap orang harus melakukan little-endian dari awal maka semuanya akan lebih sederhana. (Saya akan baik-baik saja dengan big-endian juga.) Sebaliknya, beberapa orang menerapkannya satu cara, beberapa yang lain, dan sekarang kita terjebak dengan kekonyolan untuk apa-apa. Terkadang memalukan menjadi insinyur perangkat lunak.
sumber
Saya tidak berpikir itu berbahaya jika pengembang cukup hati-hati.
Dan mereka harus menerima pertukaran ini jika mereka tahu juga.
Sebagai pengembang perangkat lunak Jepang, saya menemukan UCS-2 cukup besar dan membatasi ruang tampaknya menyederhanakan logika dan mengurangi memori runtime, jadi menggunakan utf-16 di bawah batasan UCS-2 cukup baik.
Ada filesystem atau aplikasi lain yang menganggap codepoint dan byte proporsional, sehingga nomor codepoint mentah dapat dijamin sesuai dengan beberapa penyimpanan ukuran tetap.
Salah satu contoh adalah NTFS dan VFAT menentukan UCS-2 sebagai pengkodean penyimpanan nama file mereka.
Jika contoh tersebut benar-benar ingin diperluas untuk mendukung UCS-4, saya bisa setuju menggunakan utf-8 untuk semuanya, tetapi panjang tetap memiliki poin yang baik seperti:
Di masa depan ketika memori / kekuatan pemrosesan murah bahkan di perangkat embed, kami dapat menerima perangkat menjadi agak lambat untuk kesalahan cache tambahan atau kesalahan halaman dan penggunaan memori tambahan, tetapi ini tidak akan terjadi dalam waktu dekat saya kira ...
sumber
Sangat mungkin, tetapi alternatifnya tidak harus dipandang sebagai jauh lebih baik.
Masalah mendasar adalah bahwa ada banyak konsep berbeda tentang: mesin terbang, karakter, codepoint dan urutan byte. Pemetaan antara masing-masing adalah non-sepele, bahkan dengan bantuan perpustakaan normalisasi. (Sebagai contoh, beberapa karakter dalam bahasa Eropa yang ditulis dengan skrip berbasis Latin tidak ditulis dengan satu titik kode Unicode. Dan itu adalah akhir dari kerumitan yang lebih sederhana!) Apa artinya ini adalah untuk mendapatkan semuanya dengan benar sangat menakjubkan sulit; bug aneh diharapkan (dan bukannya hanya mengeluh tentang mereka di sini, beri tahu pengelola perangkat lunak yang bersangkutan).
Satu-satunya cara di mana UTF-16 dapat dianggap berbahaya sebagai kebalikan dari, katakanlah, UTF-8 adalah bahwa ia memiliki cara berbeda untuk menyandikan titik kode di luar BMP (sebagai pasangan pengganti). Jika kode ingin mengakses atau beralih berdasarkan titik kode, itu berarti perlu menyadari perbedaannya. OTOH, itu berarti bahwa tubuh substansial dari kode yang ada yang mengasumsikan "karakter" selalu dapat masuk ke dalam kuantitas dua byte - asumsi yang cukup umum, jika salah, - setidaknya dapat terus bekerja tanpa membangun kembali semuanya. Dengan kata lain, setidaknya Anda bisa melihat karakter yang tidak ditangani dengan benar!
Saya akan memutar pertanyaan Anda dan mengatakan bahwa seluruh shebang sialan Unicode harus dianggap berbahaya dan semua orang harus menggunakan pengkodean 8-bit, kecuali saya telah melihat (selama 20 tahun terakhir) di mana itu mengarah: mengerikan kebingungan atas berbagai pengkodean ISO 8859, ditambah seluruh rangkaian yang digunakan untuk Cyrillic, dan paket EBCDIC, dan ... yah, Unicode untuk semua kesalahannya mengalahkan itu. Kalau saja itu bukan kompromi jahat antara kesalahpahaman berbagai negara.
sumber