Kalkulator Panjang String

Saat Anda menempelkan sebuah string, alat tersebut akan melaporkan panjangnya dalam empat bentuk yang berbeda: .length bergaya JavaScript (unit kode UTF-16), titik kode Unicode, kluster grafem (yang dipahami pengguna sebagai satu karakter), dan byte UTF-8 (yang sebenarnya disimpan dalam kolom basis data). Nilai-nilai ini sering tidak konsisten untuk string yang mengandung emoji, tanda bendera, atau simbol kombinasi, dan ketidaksesuaian inilah yang menjadi penyebab banyak bug.

Empat cara memaknai panjang string

  1. 1

    Unit kode UTF-16

    Nilai yang dikembalikan oleh `str.length` dalam JavaScript: 1 untuk sebagian besar karakter, dan 2 untuk setiap titik kode yang berada di luar rentang U+FFFF (seperti emoji dan aksara kuno).

  2. 2

    Titik kode

    Satu per skalar Unicode. Setiap emoji terdiri dari satu elemen; sedangkan urutan ZWJ terdiri dari beberapa elemen.

  3. 3

    Kluster grafem

    Apa yang disebut pengguna sebagai “satu karakter”. `🇺🇸` terdiri dari 2 titik kode namun hanya 1 grafem; demikian pula dengan `n̈`.

  4. 4

    Byte UTF-8

    Data yang disimpan oleh basis data Anda: ASCII = masing-masing 1 byte; karakter umum Eropa = 2 byte; karakter CJK = 3 byte; sebagian besar emoji = 4 byte.

Contoh-contoh

String JS .length Jumlah titik kode Grafem Byte UTF-8
hello 5 5 5 5
café 4 4 4 5
😀 2 1 1 4
🇺🇸 4 2 1 8
👨‍👩‍👧 (keluarga) 8 5 1 18
n̈ (n + trema) 2 2 1 3

Mengapa angka-angka berbeda

String JavaScript menggunakan format UTF-16; oleh karena itu, nilai kode yang melebihi batas U+FFFF disimpan dalam bentuk pasangan pengganti, yaitu dua unit kode UTF-16, misalnya "😀".length === 2. Pengguna sangat tidak menyukai hal ini karena mereka menganggap 😀 sebagai satu karakter tunggal.

Grafem memiliki fungsi yang lebih luas: bendera suatu negara terdiri dari dua kode indikator regional yang oleh pengguna dilihat sebagai satu bendera utuh. Contohnya adalah "🇺🇸".length === 4 dalam JavaScript, meskipun terasa tidak masuk akal, namun memang demikian adanya. Untuk mengolah grafem secara berulang, gunakan pustaka Intl.Segmenter (versi modern), grapheme-splitter, atau lakukan secara manual.

Byte UTF-8: apa yang disimpan oleh basis data Anda

Untuk kolom dengan tipe VARCHAR(255):

  • Di MySQL utf8 (yang sebenarnya menggunakan format utf8mb3), angka 255 mengacu pada jumlah byte; sedangkan café membutuhkan 5 byte, sehingga dapat menampung 51 salinan.
  • Di MySQL utf8mb4 (UTF-8 asli yang mencakup emoji), data tetap dihitung dalam byte, namun pengkodeannya mendukung urutan empat byte.
  • Di Postgres VARCHAR(255), angka 255 merujuk pada karakter (titik kode), bukan byte.
  • Pada SQL Server VARCHAR, nilainya bervariasi tergantung pada metode pengurutan (collation); sedangkan NVARCHAR menghitung unit UCS-2 sepanjang 2 byte.

Jika Anda menentukan ukuran bidang basis data berdasarkan batas karakter yang terlihat oleh pengguna, gunakan nilai bytes × 4 sebagai langkah keamanan untuk kolom dalam format UTF-8, setiap grafem dapat memakan hingga 4 byte per titik kode, dan urutan ZWJ akan menambah biaya penyimpanan lebih lanjut.

Penghitungan karakter ala Twitter

Twitter menghitung jumlah tweet berdasarkan aturan khusus: kode dihitung sebagai satu karakter, sedangkan emoji dan ideograf CJK dihitung sebanyak dua karakter. Sebuah tweet yang sepenuhnya menggunakan huruf ASCII dapat mencapai maksimal 280 karakter; sementara tweet yang menggunakan 140 emoji hanya dapat mencapai maksimal 140 karakter.

Jumlah karakter SMS: maksimal 160 karakter dalam format GSM 7-bit. Setiap karakter yang tidak termasuk dalam standar GSM (seperti á, é, ñ, atau emoji) akan mengubah pengkodean menjadi UCS-2, sehingga panjang pesan Anda berkurang menjadi 70 karakter.

Aplikasi Praktis

  • Penentuan ukuran kolom database, periksa jumlah byte sebelum melakukan migrasi.
  • Penerapan kuota API, sebagian besar API menghitung dalam satuan byte, bukan karakter.
  • Validasi formulir, menampilkan jumlah karakter yang akurat kepada pengguna sesuai dengan ekspektasi mereka (grafem).
  • Debugging kinerja, mengapa regex ini berjalan lambat? Karena data masukan 3 kali lebih panjang dalam satuan kode dibandingkan dalam satuan grafem.

Pertanyaan yang Sering Diajukan

Emoji tersebut merupakan urutan ZWJ yang terdiri dari beberapa titik kode (misalnya, emoji keluarga terdiri dari 7 titik kode). Twitter menghitungnya sebagai 2 karakter sesuai aturan bobot Unicode; sedangkan editor Anda menampilkan hanya 1 grafem. Kedua penilaian tersebut secara teknis benar, meskipun mereka mengukur hal yang berbeda.

Dalam basis data berformat UTF-8, disarankan menggunakan 4 byte untuk setiap karakter yang diharapkan demi keamanan. Bidang berisi 100 karakter (grafem) sebaiknya berupa jenis VARCHAR dengan ukuran 400 byte; jika basis data Anda mendukung karakter seperti yang digunakan oleh Postgres, gunakan VARCHAR(100) dengan pengaturan karakter set yang sesuai.

Dalam JavaScript, panjangnya bergantung pada bentuk komposisi karakternya. Komposisi NFC (U+00E1) memiliki panjang 1; sedangkan komposisi NFD yang terurai (U+0061 + U+0301) memiliki panjang 2. Karakter yang tampak sama, tetapi urutan byte-nya berbeda.

Emoji keluarga dan profesi merupakan urutan panjang ZWJ. Font yang tidak mendukung sepenuhnya akan menampilkan setiap kode sebagai karakter terpisah; oleh karena itu, 👨‍💻 menjadi 👨+💻. Pembaruan font sistem operasi dapat memperbaiki masalah ini.

Alat Terkait

Alat ini tersedia dalam bahasa lain