cv.cm

Pengetahuan · Teks, data, dan keamanan

Apa beda Unicode dan UTF-8?

4 menit baca

Jawaban singkat

Unicode adalah set karakter: setiap karakter diberi nomor yang disebut code point, misalnya U+00E9 untuk "é". UTF-8 adalah encoding: aturan untuk menyimpan nomor-nomor itu sebagai byte. UTF-8 memakai 1 byte untuk ASCII dan 2 hingga 4 byte untuk karakter lainnya, sehingga "é" menjadi C3 A9. Unicode menentukan karakter mana; UTF-8 menentukan cara karakter itu ditulis ke disk atau dikirim lewat jaringan.

Buka Hex

Code point dulu, byte kemudian

Unicode mendefinisikan ruang kode dari U+0000 sampai U+10FFFF, cukup untuk 1.114.112 code point yang dibagi menjadi 17 plane masing-masing berisi 65.536. Lebih dari 150.000 di antaranya sudah ditetapkan untuk karakter, mencakup aksara modern dan kuno, simbol, serta emoji. Code point ditulis sebagai U+ diikuti minimal empat digit heksadesimal.

Code point hanyalah sebuah angka. Untuk menyimpan atau mengirim teks, angka itu harus diubah menjadi byte, dan ada beberapa cara melakukannya: UTF-8, UTF-16, dan UTF-32 semuanya adalah encoding untuk karakter Unicode yang sama.

KarakterCode pointByte UTF-8UTF-16 (big-endian)
AU+00414100 41
éU+00E9C3 A900 E9
€U+20ACE2 82 AC20 AC
日U+65E5E6 97 A565 E5
😀U+1F600F0 9F 98 80D8 3D DE 00

Bagaimana UTF-8 memilih 1, 2, 3, atau 4 byte

UTF-8, yang dispesifikasikan dalam RFC 3629, adalah encoding dengan lebar variabel. Bit-bit awal pada byte pertama menunjukkan berapa byte yang menyusul, dan setiap byte lanjutan diawali bit 10. Hal ini membuat aliran data dapat menyinkronkan diri: decoder yang mendarat di tengah karakter bisa melompat ke byte awal berikutnya.

Rentang code pointBytePola bit
U+0000 – U+007F10xxxxxxx
U+0080 – U+07FF2110xxxxx 10xxxxxx
U+0800 – U+FFFF31110xxxx 10xxxxxx 10xxxxxx
U+10000 – U+10FFFF411110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Contoh perhitungan: "é" adalah U+00E9, dalam biner 000 1110 1001. Karakter ini butuh pola 2 byte. Lima bit teratas 00011 dimasukkan ke 110xxxxx sehingga menjadi 11000011 (C3), dan enam bit terbawah 101001 dimasukkan ke 10xxxxxx sehingga menjadi 10101001 (A9).

Karena 128 code point pertama di-encode menjadi byte tunggal yang sama dengan ASCII, setiap file ASCII yang valid otomatis juga UTF-8 yang valid. Kompatibilitas mundur inilah alasan utama UTF-8 menjadi default di web, yang dipakai oleh sekitar 98% situs web.

UTF-8 vs UTF-16 vs UTF-32

EncodingUkuran unitByte per karakterUmum dipakai di
UTF-88 bit1–4Halaman web, JSON, file Linux dan macOS, sebagian besar API
UTF-1616 bit2 atau 4String JavaScript, Java, API Windows
UTF-3232 bitSelalu 4Pemrosesan internal yang diuntungkan oleh lebar tetap

UTF-16 menyimpan karakter di atas U+FFFF sebagai pasangan surrogate yang terdiri dari dua unit 16-bit. Itulah sebabnya "😀".length bernilai 2 di JavaScript: bahasa ini menghitung unit UTF-16, bukan karakter. Iterasi dengan [..."😀"].length menghasilkan 1.

Untuk teks bahasa Inggris, UTF-8 paling ringkas. Untuk teks yang sebagian besar berbahasa Tionghoa, Jepang, atau Korea, UTF-16 bisa lebih kecil, karena karakter tersebut memakan 3 byte di UTF-8 tetapi 2 byte di UTF-16.

Byte order mark (BOM)

BOM adalah karakter U+FEFF yang diletakkan di awal file. Pada UTF-16 dan UTF-32, BOM memberi tahu pembaca apakah byte-nya big-endian atau little-endian. Pada UTF-8, BOM di-encode sebagai EF BB BF dan hanya berfungsi sebagai penanda, karena UTF-8 tidak punya urutan byte.

FAQ Unicode menyatakan BOM UTF-8 tidak diwajibkan dan tidak disarankan. Sebagian editor Windows tetap menambahkannya, lalu BOM itu merusak skrip shell (baris #! tidak lagi berada paling awal), header CSV, dan parser JSON yang tidak mengharapkannya. Jika sebuah file menampilkan  di bagian atas, itu adalah BOM UTF-8 yang dibaca sebagai Windows-1252.

Mengapa teks berubah menjadi é atau ���

Teks kacau, yang disebut mojibake, muncul saat byte di-decode dengan encoding yang berbeda dari encoding saat ditulis:

  • é alih-alih é: byte UTF-8 C3 A9 dibaca sebagai Windows-1252 atau Latin-1, yang memetakan C3 ke à dan A9 ke ©.
  • � (U+FFFD, karakter pengganti): decoder menemukan byte yang bukan UTF-8 valid, sering kali teks Latin-1 yang dibaca sebagai UTF-8.
  • Tanda tanya di database: kolom atau koneksinya memakai charset yang tidak bisa menampung karakter tersebut, sehingga karakter itu diganti saat ditulis dan hilang selamanya.

Solusinya adalah menyatakan encoding di setiap batas: <meta charset="utf-8"> di HTML, Content-Type: text/html; charset=utf-8 di header HTTP, serta UTF-8 untuk kolom dan koneksi database. Di MySQL, gunakan utf8mb4; charset utf8 yang lebih lama hanya menyimpan maksimal 3 byte per karakter dan menolak emoji.

FAQ

Apakah UTF-8 sama dengan Unicode?

Tidak. Unicode adalah daftar karakter beserta nomornya; UTF-8 adalah salah satu cara menyimpan nomor-nomor itu sebagai byte. Orang sering menyebut "Unicode" padahal maksudnya teks UTF-8.

Berapa byte satu karakter di UTF-8?

Antara 1 dan 4. Huruf ASCII memakan 1 byte, sebagian besar huruf beraksen Eropa 2 byte, sebagian besar karakter Tionghoa, Jepang, dan Korea 3 byte, dan emoji 4 byte.

Apakah UTF-8 bisa merepresentasikan semua karakter?

Ya. UTF-8 bisa meng-encode setiap code point Unicode dari U+0000 sampai U+10FFFF, jadi karakter apa pun yang didefinisikan Unicode bisa ditulis dalam UTF-8.

Apakah file sebaiknya disimpan dengan BOM?

Untuk UTF-8, biasanya tidak. BOM bersifat opsional, tidak berguna untuk urutan byte, dan membingungkan alat yang mengharapkan byte pertama berupa isi file. Sebagian versi Excel lama membutuhkannya agar bisa membuka file CSV UTF-8 dengan benar.

Semua artikel pengetahuan