Kenapa ini penting
Hampir semua program mengolah teks: nama pengguna, pesan chat, alamat email, isi artikel, sampai kode program itu sendiri. Kamu sudah tahu komputer hanya menyimpan angka. Lalu bagaimana huruf "A", tanda "@", atau huruf "é" bisa tersimpan? Jawabannya: lewat tabel kesepakatan yang memetakan setiap karakter ke sebuah angka. Kalau kamu paham konsep ini, kamu tidak akan bingung saat melihat tulisan rusak seperti Café di website, atau saat panjang teks yang dihitung program ternyata berbeda dengan yang kamu lihat. Detail teknis standar seperti ASCII dan UTF-8 dibahas lebih dalam di modul Character translation systems. Di sini kita bangun intuisinya dulu.
Konsep inti
Karakter, glyph, dan kode
Ada tiga hal berbeda yang sering dicampuradukkan:
- Karakter adalah unit makna dalam teks: huruf
A, angka7, tanda?, spasi, bahkan "baris baru". - Kode (code point) adalah nomor yang disepakati untuk karakter itu. Misalnya
Abernomor 65. - Glyph adalah bentuk visual karakter di layar, yang bergantung pada font. Huruf
Adi font Arial dan Times New Roman bentuknya beda, tapi karakternya sama dan nomornya tetap 65.
Analogi: nomor antrean di bank. Nomor "65" adalah kodenya, orang yang dipanggil adalah karakternya, sedangkan pakaian yang ia pakai hari itu adalah glyph-nya. Pakaiannya bisa ganti, tapi orangnya dan nomornya tetap.
Character set dan encoding
- Character set adalah daftar karakter beserta nomornya. Contohnya ASCII (128 karakter) dan Unicode (lebih dari 150 ribu karakter dari hampir semua aksara dunia, termasuk aksara Jawa dan emoji).
- Encoding adalah aturan cara menyimpan nomor itu sebagai byte. Contohnya UTF-8 dan UTF-16.
Kenapa perlu dua lapis? Karena nomor karakter bisa besar (emoji 😀 bernomor 128512), sedangkan satu byte hanya menampung 0-255. Encoding menentukan berapa byte yang dipakai dan bagaimana urutannya.
Teks disimpan sebagai deretan angka
Kata Hai disimpan kira-kira begini:
| Karakter | H | a | i |
|---|---|---|---|
| Kode | 72 | 97 | 105 |
| Biner | 01001000 | 01100001 | 01101001 |
Perhatikan bahwa huruf besar dan huruf kecil punya kode berbeda: A = 65, a = 97. Bagi komputer, "Budi" dan "budi" adalah dua teks yang berbeda. Inilah sebabnya pencarian dan login sering mengubah teks ke huruf kecil dulu sebelum dibandingkan.
Karakter tak terlihat
Tidak semua karakter terlihat. Spasi punya kode 32. Baris baru (newline, ditulis \n dalam kode) punya kode 10. Tab (\t) punya kode 9. Windows tradisionalnya memakai dua karakter untuk baris baru (\r\n), sedangkan Linux dan macOS memakai satu (\n). Perbedaan kecil ini kadang bikin file teks terlihat "berantakan" saat dipindah antar sistem.
Urutan abjad versi komputer
Karena teks adalah angka, membandingkan teks sebenarnya membandingkan kode karakter satu per satu dari kiri. Akibatnya:
"B" < "a"bernilaitrue, karena 66 lebih kecil dari 97 (semua huruf besar ada sebelum huruf kecil)."10" < "9"bernilaitrue, karena yang dibandingkan karakter pertama:"1"(49) lebih kecil dari"9"(57).
Ini sumber bug klasik saat mengurutkan data. Solusinya akan kamu pelajari nanti (misalnya localeCompare untuk teks dan perbandingan angka untuk angka).
Mojibake: teks rusak karena salah encoding
Kalau teks disimpan dengan satu encoding tapi dibaca dengan encoding lain, hasilnya kacau. Contoh: kata Café disimpan sebagai UTF-8, tapi dibaca sebagai encoding lama Latin-1, maka tampil sebagai Café. Fenomena ini disebut mojibake (istilah Jepang untuk "karakter berubah bentuk"). Pencegahannya sederhana: pakai UTF-8 di mana-mana dan cantumkan <meta charset="UTF-8"> di setiap halaman HTML.
Contoh kode
// Melihat kode karakter dari setiap huruf
const kata = "Hai";
for (const huruf of kata) {
console.log(huruf, "→", huruf.charCodeAt(0));
}
// → H → 72
// → a → 97
// → i → 105
// Huruf besar dan kecil itu berbeda bagi komputer
console.log("Budi" === "budi"); // → false
console.log("Budi".toLowerCase() === "budi".toLowerCase()); // → true
// Perbandingan teks = perbandingan kode karakter
console.log("B" < "a"); // → true (66 < 97)
console.log("10" < "9"); // → true ("1" = 49 lebih kecil dari "9" = 57)
// Mengurutkan nama tanpa peduli huruf besar/kecil
const nama = ["budi", "Andi", "citra", "Dewi"];
console.log([...nama].sort());
// → [ 'Andi', 'Dewi', 'budi', 'citra' ] (huruf besar duluan)
console.log([...nama].sort((a, b) => a.localeCompare(b)));
// → [ 'Andi', 'budi', 'citra', 'Dewi' ]
Karakter tak terlihat dan jumlah byte:
const teks = "Baris 1\nBaris 2";
console.log(teks);
// → Baris 1
// → Baris 2
console.log("\n".charCodeAt(0)); // → 10
console.log(" ".charCodeAt(0)); // → 32
// Jumlah karakter tidak selalu sama dengan jumlah byte
const enc = new TextEncoder(); // encoding UTF-8
console.log("A".length, enc.encode("A").length); // → 1 1
console.log("é".length, enc.encode("é").length); // → 1 2
Kesalahan umum
- Membandingkan teks tanpa menyamakan huruf besar/kecil. Email
Budi@Mail.comdanbudi@mail.comdianggap berbeda. Normalisasi dulu dengantoLowerCase()sebelum membandingkan. - Mengurutkan angka yang disimpan sebagai teks.
["10", "9", "2"].sort()menghasilkan["10", "2", "9"]. Ubah ke angka dulu sebelum diurutkan. - Lupa
<meta charset="UTF-8">di HTML. Tanpa ini, browser bisa salah menebak encoding dan huruf beraksen atau emoji jadi rusak. - Menganggap 1 karakter = 1 byte. Itu hanya berlaku untuk karakter ASCII dasar. Huruf
ébutuh 2 byte di UTF-8, emoji butuh 4 byte.
Latihan
- Mudah, Cari tahu kode karakter dari huruf pertama namamu dan dari tanda
@menggunakancharCodeAt. - Sedang, Tulis kode yang membandingkan dua username
"AdminKu"dan" adminku "sehingga dianggap sama. Petunjuk:trim()menghapus spasi di awal dan akhir. - Menantang, Tampilkan setiap karakter dari kata
"Kode"beserta kodenya dalam bentuk biner 8 bit, misalnyaK → 01001011.
Lihat solusi
1.
console.log("S".charCodeAt(0)); // → 83 (contoh untuk nama "Sari")
console.log("@".charCodeAt(0)); // → 64
2.
const a = "AdminKu";
const b = " adminku ";
const normal = (s) => s.trim().toLowerCase();
console.log(normal(a) === normal(b)); // → true
3.
for (const huruf of "Kode") {
const biner = huruf.charCodeAt(0).toString(2).padStart(8, "0");
console.log(`${huruf} → ${biner}`);
}
// → K → 01001011
// → o → 01101111
// → d → 01100100
// → e → 01100101
Ringkasan
- Teks disimpan sebagai deretan angka. Setiap karakter punya nomor (code point).
- Character set = daftar karakter dan nomornya. Encoding = cara menyimpan nomor itu ke byte.
- Glyph adalah tampilan karakter yang bergantung font. Karakternya sendiri tidak berubah.
- Huruf besar dan kecil punya kode berbeda, dan perbandingan teks memakai kode karakter.
- Salah encoding menyebabkan mojibake. Gunakan UTF-8 secara konsisten.