Tujuannya adalah untuk membuat konverter yang sepenuhnya sesuai antara pengkodean Unicode resmi seperti yang diberikan dalam FAQ UTF . Mengingat bahwa ini berpusat pada Unicode, saya akan menerima jawaban dengan jumlah byte terendah menggunakan yang terbaik dari pengkodean yang terlibat (yang mungkin akan menjadi UTF-8, kecuali mungkin Anda memprogramnya di APL). Saya minta maaf atas posting lama, tetapi banyak yang menjelaskan tentang pengkodean yang juga dapat diakses dalam spesifikasi resmi (pdf, bagian 3.9 D90 - D92) , atau Wikipedia .
Spesifikasi
Jika suatu saat bahasa pilihan Anda tidak dapat secara tepat memenuhi persyaratan, gantikan dengan sesuatu yang melekat pada semangat aturan yang diberikan. Misalnya. tidak setiap bahasa memiliki susunan bawaan, fungsi dll.
Tidak menggunakan string libraries / functions, atau encoding libraries / functions. Inti dari kode golf ini adalah untuk mengimplementasikan konverter menggunakan manipulasi bit / byte. Menggunakan string sendiri dalam kapasitasnya sebagai karakter atau byte array diperbolehkan. Oh, dan tidak ada panggilan OS yang melakukan konversi.
Konverter adalah fungsi yang akan mengambil tiga parameter: array byte yang mewakili string input yang dikodekan, dan pengkodean "input" dan "output" direpresentasikan sebagai angka. Secara sewenang-wenang kami akan menetapkan
UTF-8, UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, and UTF32LE
angka dari 0 hingga 6 dalam urutan itu. Tidak perlu memeriksa apakah nomornya< 0
atau> 6
, kami akan menganggap parameter ini benar. Konverter akan mengembalikan array byte yang valid dalam pengkodean output yang diinginkan.Kami akan menggunakan karakter nol (
U+0000
) sebagai terminator string. Apa pun setelah ini tidak masalah. Kami akan menganggap bahwa array input memiliki karakter nol di suatu tempat sehingga Anda tidak perlu melakukan pemeriksaan batas.Sesuai FAQ , jika array byte input tidak valid untuk pengkodean yang dinyatakannya, kami harus memberi sinyal kesalahan. Kami akan melakukan ini dalam salah satu cara berikut: crash program, lempar pengecualian, kembalikan null atau kembalikan array yang empat byte pertamanya semuanya 0 (sehingga dapat dikenali
U+0000
dalam setiap penyandian).
Pengkodean
Spesifikasi resmi harus dipatuhi, tetapi Wikipedia memberikan penjelasan yang baik (dan sejauh yang saya yakini benar) dari pengkodean, dan saya akan meringkasnya di sini untuk kelengkapan. Perhatikan bahwa UTF-16 dan UTF-32 memiliki varian untuk endianness .
UTF-32, UTF-32LE, UTF-32BE
Pengkodean paling sederhana, setiap titik kode hanya dikodekan dalam 4 byte sama dengan nilai numeriknya. LE / BE mewakili endianness (little endian / big endian).
UTF-16, UTF-16LE, UTF-16BE
Poin kode dari U+0000 - U+FFFF
dikodekan dalam 2 byte sama dengan nilai numeriknya. Nilai yang lebih besar dikodekan menggunakan sepasang pengganti yang merupakan nilai yang dicadangkan dari U+D800 - U+DFFF
. Jadi untuk menyandikan poin lebih besar dari itu U+FFFF
, algoritma berikut ini dapat digunakan (disalin tanpa malu-malu dari Wikipedia ):
- 0x010000 dikurangi dari titik kode, meninggalkan angka 20 bit di kisaran 0..0x0FFFFF.
- Sepuluh bit teratas (angka dalam kisaran 0..0x03FF) ditambahkan ke 0xD800 untuk memberikan unit kode pertama atau pengganti pengganti, yang akan berada dalam kisaran 0xD800..0xDBFF [...].
- Sepuluh bit rendah (juga dalam kisaran 0..0x03FF) ditambahkan ke 0xDC00 untuk memberikan unit kode kedua atau pengganti jejak, yang akan berada dalam kisaran 0xDC00..0xDFFF [...].
UTF-8
Poin kode dari U+0000 - U+007F
dikodekan sebagai 1 byte sama dengan nilai numeriknya. Dari U+0080 - U+07FF
mereka dikodekan sebagai 110xxxxx 10xxxxxx
, U+0800 - U+FFFF
adalah 1110xxxx 10xxxxxx 10xxxxxx
, nilai yang lebih tinggi 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
. Ini x
adalah bit dari nilai numerik dari titik kode.
BOM
Tanda byte-order (BOM, U+FEFF
) digunakan sebagai titik kode pertama untuk menunjukkan endianness. Mengikuti pedoman FAQ tentang BOM, BOM akan digunakan sebagai berikut: Untuk UTF-8, UTF-16 and UTF-32
itu opsional. Jika BOM tidak ada di UTF-16
atau UTF-32
, diasumsikan sebagai big endian. BOM tidak boleh muncul diUTF-16LE, UTF-16BE, UTF-32LE and UTF-32BE
.
Kesalahan Umum Menyebabkan UTF Tidak Valid
Berbagai hal dapat menyebabkan urutan byte menjadi UTF tidak valid.
- UTF-8 dan UTF-32: Langsung menyandikan poin kode pengganti (
U+D800 - U+DFFF
), atau poin kode lebih besar dariU+10FFFF
. - UTF-8: Banyak urutan byte yang tidak valid.
- UTF-16: pengganti yang berpasangan atau tidak berpasangan.
- BOM: Harus digunakan seperti yang ditentukan di bagian penyandian. Perhatikan bahwa ketika mengeluarkan
UTF-16
atauUTF-32
(tidak ditentukan endianness inheren) Anda dapat memilih, tetapi dengan sedikit endian, Anda harus memasukkan BOM.
Perhatikan bahwa non-karakter dan titik kode yang tidak ditetapkan (keduanya berbeda dari pengganti) harus diperlakukan seperti karakter biasa.
''⎕R''⍠'InEnc' 'UTF16BE' 'OutEnc' 'UTF8-BOM'
,.