Apa Itu SMS Counter?
SMS counter adalah alat yang menghitung berapa banyak karakter yang terkandung dalam pesan Anda, mendeteksi jenis encoding (GSM 7-bit atau UCS-2), dan menentukan berapa banyak segmen SMS yang akan dipecah. Ini penting karena operator seluler mengenakan biaya per segmen, bukan per pesan, dan melebihi batas satu-SMS dapat menggandakan atau melipatgandakan biaya Anda tanpa peringatan.
Tidak seperti penghitung karakter biasa, SMS counter memperhitungkan batasan teknis standar Short Message Service yang didefinisikan dalam GSM 03.38. Ini mempertimbangkan tidak hanya panjang teks Anda, tetapi karakter apa yang dikandungnya dan bagaimana mereka harus di-encode untuk transmisi melalui jaringan seluler.
Cara Kerja Encoding GSM 7-Bit
Spesifikasi GSM 03.38 mendefinisikan alfabet default 128 karakter yang dapat di-encode menggunakan 7 bit masing-masing. Ini mencakup huruf Latin besar dan kecil, digit, tanda baca umum, dan beberapa simbol khusus. Karena setiap karakter hanya menggunakan 7 bit, satu SMS dapat memuat hingga 160 karakter — dihitung sebagai (140 byte × 8 bit) / 7 bit per karakter.
Set karakter dasar GSM 7-bit:
| Kategori | Karakter |
|---|---|
| Huruf | A–Z, a–z |
| Digit | 0–9 |
| Tanda baca | @, !, ", #, $, %, &, ', (, ), *, +, ,, -, ., / |
| Simbol | :, ;, <, =, >, ?, ¡, ¿, ¤, £, ¥, §, ¨, ©, ®, ´, `, ^, ~, ¯ |
| Khusus | Spasi, baris baru, carriage return |
| Diperluas | ^, {, }, , [, ~, ], , € (memerlukan byte escape) |
Karakter GSM 7-bit yang diperluas — seperti ^, {, }, [, ], ~, |, dan € — memerlukan kode escape (0x1B) sebelum karakter. Byte escape ini mengkonsumsi ruang dalam pesan, sehingga setiap karakter yang diperluas secara efektif dihitung sebagai 2 karakter terhadap batas 160 karakter.
Encoding UCS-2: Ketika 7 Bit Tidak Cukup
Ketika pesan Anda berisi karakter di luar alfabet GSM 7-bit — seperti emoji, tanda kutip melengkung, huruf beraksen seperti é atau ü, garis pisah seperti —, atau simbol Unicode apa pun — seluruh pesan beralih ke encoding UCS-2 (16-bit). Dalam mode UCS-2, setiap karakter menempati 16 bit, mengurangi kapasitas satu-SMS dari 160 menjadi 70 karakter.
Karakter yang memaksa encoding UCS-2:
- Emoji dan piktograf (
😊,🚀,❤️) - Tanda kutip melengkung (
"",'') - Garis pisah panjang (
—,–) - Karakter beraksen yang tidak ada di set dasar GSM (
ě,ř,č) - Simbol mata uang di luar
$,£,¥,€ - Panah (
→,←,↑,↓) - Simbol matematika (
∑,∫,√,∞) - Sebagian besar karakter CJK (Cina, Jepang, Korea)
Setelah pesan berisi satu karakter UCS-2, seluruh pesan menggunakan encoding 16-bit. Tidak ada mode hybrid — semuanya 7-bit atau semuanya 16-bit.
SMS Multipart dan Batas Segmen
Ketika pesan Anda melebihi batas satu-SMS (160 karakter GSM atau 70 karakter UCS-2), operator membaginya menjadi beberapa segmen. Setiap segmen menyertakan header data pengguna (UDH) 6-byte untuk perakitan ulang, yang mengurangi ruang payload yang tersedia.
| Encoding | SMS Tunggal | Multipart (per segmen) |
|---|---|---|
| GSM 7-bit | 160 karakter | 153 karakter |
| UCS-2 | 70 karakter | 67 karakter |
Cara perhitungannya:
GSM 7-bit multipart:
characters_per_segment = (140 - 6) × 8 / 7 = 153
UCS-2 multipart:
characters_per_segment = (140 - 6) / 2 = 67
Pesan 200 karakter dalam encoding GSM 7-bit terbagi menjadi 2 segmen (153 + 47). Pesan 150 karakter yang mengandung emoji terbagi menjadi 3 segmen UCS-2 (67 + 67 + 16). Sebagian besar operator menagih per segmen, jadi memahami batas ini membantu Anda mengontrol biaya.
Contoh Kode
PHP: Hitung Segmen SMS
function countSmsSegments(string $text): array {
$gsm7 = '@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà';
$gsm7ext = ['^', '{', '}', '\\', '[', '~', ']', '|', '€'];
$isUcs2 = false;
$extCount = 0;
for ($i = 0; $i < mb_strlen($text); $i++) {
$char = mb_substr($text, $i, 1);
if (in_array($char, $gsm7ext)) {
$extCount++;
} elseif (mb_strpos($gsm7, $char) === false) {
$isUcs2 = true;
break;
}
}
if ($isUcs2) {
$maxPerSegment = 70;
$segments = (int)ceil(mb_strlen($text) / $maxPerSegment);
// Multipart reduces limit
if ($segments > 1) {
$maxPerSegment = 67;
$segments = (int)ceil(mb_strlen($text) / $maxPerSegment);
}
return ['encoding' => 'UCS-2', 'segments' => $segments, 'chars_per_segment' => $maxPerSegment];
}
$effectiveLength = mb_strlen($text) + $extCount;
$maxPerSegment = 160;
$segments = (int)ceil($effectiveLength / $maxPerSegment);
if ($segments > 1) {
$maxPerSegment = 153;
$segments = (int)ceil($effectiveLength / $maxPerSegment);
}
return ['encoding' => 'GSM 7-bit', 'segments' => $segments, 'chars_per_segment' => $maxPerSegment];
}
JavaScript: Deteksi Encoding SMS
const GSM7_BASIC = new Set(
'@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡' +
'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà'.split('')
);
const GSM7_EXT = new Set(['^', '{', '}', '\\', '[', '~', ']', '|', '€']);
function detectSmsEncoding(text) {
let extCount = 0;
for (const char of text) {
if (GSM7_EXT.has(char)) {
extCount++;
} else if (!GSM7_BASIC.has(char)) {
return { encoding: 'UCS-2', extCount: 0 };
}
}
return { encoding: 'GSM 7-bit', extCount };
}
const result = detectSmsEncoding('Hello World! €50');
console.log(result); // { encoding: 'GSM 7-bit', extCount: 1 }
Python: Hitung Bagian SMS
def sms_parts(text: str) -> dict:
gsm7_basic = set('@£$¥èéùìòÇØøÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&\'()*+,-./0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà')
gsm7_ext = {'^', '{', '}', '\\', '[', '~', ']', '|', '€'}
is_ucs2 = False
ext_count = 0
for char in text:
if char in gsm7_ext:
ext_count += 1
elif char not in gsm7_basic:
is_ucs2 = True
break
if is_ucs2:
limit = 70 if len(text) <= 70 else 67
parts = (len(text) + limit - 1) // limit
return {'encoding': 'UCS-2', 'parts': parts, 'chars_per_part': limit}
effective = len(text) + ext_count
limit = 160 if effective <= 160 else 153
parts = (effective + limit - 1) // limit
return {'encoding': 'GSM 7-bit', 'parts': parts, 'chars_per_part': limit}
print(sms_parts('Hello World')) # 1 part, GSM 7-bit
print(sms_parts('Hello 😊 World')) # UCS-2 encoding triggered
Mengapa Encoding SMS Penting bagi Pengembang
Jika Anda membangun aplikasi yang mengirim notifikasi SMS — seperti kode otentikasi dua faktor, pengingat janji temu, atau kampanye pemasaran — memahami encoding SMS membantu Anda mengontrol keterkiriman dan biaya.
Hal-hal penting bagi pengembang:
- Selalu validasi panjang pesan sebelum mengirim untuk menghindari biaya multipart tak terduga
- Hapus atau ganti karakter UCS-2 jika memungkinkan untuk menjaga pesan tetap dalam GSM 7-bit
- Uji dengan karakter yang diperluas seperti
€dan[]— mereka terkompresi berbeda dari karakter GSM dasar - Perhitungkan overhead UDH 6-byte saat memperkirakan kapasitas multipart
- Pertimbangkan menggunakan alat SMS counter khusus selama pengembangan dan pengujian
Alat Online
Alat SMS Counter di Help2Code menyediakan penghitungan karakter real-time, deteksi encoding, dan pratinjau segmen. Tempel pesan Anda dan langsung lihat apakah menggunakan encoding GSM 7-bit atau UCS-2, berapa banyak segmen yang diperlukan, dan di mana tepatnya setiap segmen terputus. Pratinjau encoding dengan kode warna menunjukkan karakter mana yang memicu mode Unicode dan mana yang aman dalam 7-bit.
Kesimpulan
SMS counter adalah utilitas penting bagi siapa saja yang mengirim pesan teks secara terprogram atau ingin menghindari biaya operator tak terduga. Dengan memahami perbedaan antara encoding GSM 7-bit dan UCS-2, dan mengetahui cara kerja segmentasi multipart, Anda dapat menulis aplikasi SMS yang lebih hemat biaya dan men-debug masalah pengiriman lebih cepat. Gunakan alat SMS Counter untuk menguji pesan Anda sebelum mengirimnya di produksi.