Base64 adalah cara mengubah data biner menjadi teks yang hanya berisi 64 karakter aman (A–Z, a–z, 0–9, +, dan /), supaya data tersebut bisa lewat di jalur yang hanya menerima teks, seperti email, JSON, atau URL. Base64 bukan enkripsi: tidak ada kunci, tidak ada rahasia, dan siapa pun bisa mengembalikannya ke data asli dalam satu langkah.
Di artikel ini Anda akan memahami cara kerja Base64 dari level byte (kenapa 3 byte menjadi 4 karakter), fungsi tanda = di akhir, varian base64url, berapa besar ukurannya membengkak, kapan sebaiknya dipakai, dan contoh kode di JavaScript maupun PHP, termasuk jebakan UTF-8 yang sering membuat btoa() error. Kalau ingin langsung mencoba, Anda bisa memakai tool Base64 Encode/Decode sambil membaca.
Apa itu Base64 dan masalah apa yang diselesaikannya?
Komputer menyimpan semua data sebagai byte, dan satu byte bisa bernilai 0 sampai 255. Masalahnya, banyak protokol lama dan format teks tidak dirancang untuk membawa byte sembarang. Email (SMTP) awalnya hanya aman untuk teks ASCII 7-bit. Format JSON tidak punya tipe data biner. URL punya karakter khusus yang maknanya berubah kalau muncul di tempat yang salah. Kalau Anda memasukkan byte gambar PNG mentah ke dalam salah satu jalur itu, datanya bisa rusak, terpotong, atau disalahartikan.
Base64 menyelesaikan masalah ini dengan menerjemahkan byte apa pun ke dalam himpunan karakter yang sangat aman dan bisa dicetak. Hasilnya memang lebih panjang, tetapi dijamin bisa lewat hampir di mana saja tanpa berubah. Di sisi penerima, teks Base64 tinggal di-decode kembali menjadi byte yang persis sama. Standar resminya didefinisikan di RFC 4648.
Base64 bukan enkripsi (dan bukan hashing)
Ini kesalahpahaman paling berbahaya. Karena hasil Base64 terlihat seperti teks acak, sebagian developer menganggapnya "terenkripsi". Faktanya:
- Encoding (seperti Base64) mengubah format data agar bisa dikirim. Tidak ada kunci. Siapa pun yang tahu itu Base64 bisa men-decode-nya.
- Enkripsi (seperti AES) mengubah data agar tidak bisa dibaca tanpa kunci rahasia.
- Hashing (seperti SHA-256 atau bcrypt) mengubah data menjadi sidik jari satu arah yang tidak bisa dikembalikan.
Jadi menyimpan password, token API, atau data pribadi dalam bentuk Base64 sama saja dengan menyimpannya dalam teks biasa. Contoh nyatanya ada di HTTP Basic Auth dan payload JWT: keduanya memakai Base64, dan keduanya bisa dibaca siapa saja yang mencegat datanya. Itulah alasan Basic Auth wajib dipakai lewat HTTPS, dan alasan Anda tidak boleh menaruh data rahasia di payload JWT.
Cara kerja Base64: 3 byte menjadi 4 karakter
Inti algoritmanya sederhana. Base64 mengambil data per kelompok 3 byte (3 × 8 = 24 bit), lalu memecah 24 bit itu menjadi 4 potongan masing-masing 6 bit. Enam bit bisa mewakili 26 = 64 nilai (0–63), dan setiap nilai dipetakan ke satu karakter di tabel Base64:
| Nilai | Karakter |
|---|---|
| 0–25 | A–Z |
| 26–51 | a–z |
| 52–61 | 0–9 |
| 62 | + |
| 63 | / |
Mari kita encode kata Man secara manual. Kode ASCII-nya adalah M = 77, a = 97, n = 110. Dalam biner:
M a n
01001101 01100001 01101110
Dipecah per 6 bit:
010011 010110 000101 101110
19 22 5 46
T W F u
Hasilnya TWFu. Tiga byte masuk, empat karakter keluar. Proses decode adalah kebalikannya: setiap karakter diubah kembali menjadi 6 bit, digabung, lalu dipotong per 8 bit menjadi byte asli.
Padding: arti tanda = di akhir
Bagaimana jika panjang data tidak habis dibagi 3? Di sinilah padding berperan. Base64 menambahkan bit nol agar potongan terakhir lengkap, lalu menandai kekurangannya dengan karakter =:
- Sisa 1 byte → menghasilkan 2 karakter +
==. Contoh:MmenjadiTQ==. - Sisa 2 byte → menghasilkan 3 karakter +
=. Contoh:MamenjadiTWE=. - Tidak ada sisa → tanpa padding. Contoh:
ManmenjadiTWFu.
Karena itu panjang string Base64 standar selalu kelipatan 4. Kalau Anda menerima string Base64 yang panjangnya tidak kelipatan 4, kemungkinan padding-nya dibuang (umum di base64url) atau datanya terpotong saat dikirim.
base64url: varian aman untuk URL dan nama file
Karakter + dan / bermasalah di URL: / adalah pemisah path, dan + sering diartikan sebagai spasi di query string. Sementara = dipakai untuk pasangan kunci-nilai. Untuk itu RFC 4648 juga mendefinisikan base64url:
+diganti-/diganti_- Padding
=biasanya dihilangkan
Contohnya, byte 0xFB 0xFF menjadi +/8= di Base64 standar, tetapi -_8 di base64url. Varian ini dipakai di JWT, token reset password, dan ID pendek di URL. Jika Anda men-decode JWT dengan fungsi Base64 biasa dan gagal, kemungkinan besar penyebabnya adalah perbedaan alfabet atau padding ini.
Ukuran membengkak sekitar 33%
Karena setiap 3 byte menjadi 4 karakter, ukuran hasil Base64 adalah sekitar 4/3 dari ukuran asli, atau bertambah kira-kira 33%. Rumus panjang hasil (dengan padding) adalah 4 × ceil(n / 3). File 300 KB akan menjadi sekitar 400 KB setelah di-encode. Pada email MIME, ada tambahan baris baru setiap 76 karakter, sehingga overhead-nya sedikit lebih besar lagi.
Konsekuensinya praktis: jangan menyimpan file besar sebagai Base64 di database atau mengirimnya di JSON kalau ada cara lain. Upload multipart atau penyimpanan file biasa jauh lebih hemat.
Kapan Base64 dipakai di dunia nyata?
Data URI di HTML dan CSS
Anda bisa menyematkan gambar kecil langsung di HTML atau CSS dengan format data:[mime];base64,[data]. Ini menghemat satu request HTTP untuk ikon kecil, tetapi menambah ukuran HTML/CSS dan tidak bisa di-cache terpisah. Cocok untuk ikon berukuran beberapa ratus byte, tidak cocok untuk foto.
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==" alt="titik">
Lampiran email
Lampiran email dikirim dengan header Content-Transfer-Encoding: base64. Library seperti Laravel Mail atau PHPMailer melakukannya otomatis, jadi Anda jarang perlu menulisnya sendiri. Namun memahami ini membantu saat membaca sumber email mentah atau men-debug email yang rusak.
HTTP Basic Authentication
Header Basic Auth berisi username:password yang di-encode Base64:
Authorization: Basic dXNlcjpyYWhhc2lh
# hasil decode: user:rahasia
Seperti terlihat, siapa pun bisa membacanya. Basic Auth hanya aman bila seluruh koneksi memakai HTTPS. Untuk memahami peran HTTPS di sini, baca juga cara kerja HTTP dan HTTPS.
JWT dan data di API
Header dan payload JWT di-encode dengan base64url. API juga sering menerima file kecil (misalnya foto tanda tangan) sebagai string Base64 di dalam JSON. Jika Anda membangun API, pertimbangkan batas ukurannya. Konsep dasarnya dibahas di artikel apa itu REST API.
Berlangganan gratis. Artikel & tutorial coding terbaru langsung ke email kamu. Tanpa spam.
Base64 di JavaScript: btoa, atob, dan jebakan UTF-8
Browser menyediakan btoa() (encode) dan atob() (decode). Untuk teks ASCII semuanya lancar:
btoa('Hello'); // "SGVsbG8="
atob('SGVsbG8='); // "Hello"
Masalah muncul saat teks mengandung karakter di luar Latin-1, misalnya emoji, huruf Arab, atau simbol €. btoa() menganggap setiap karakter sebagai satu byte, sehingga karakter dengan kode di atas 255 langsung memicu error InvalidCharacterError:
btoa('Harga 10€'); // InvalidCharacterError
Solusi yang benar adalah mengubah string menjadi byte UTF-8 dulu memakai TextEncoder, lalu meng-encode byte tersebut:
function toBase64(str) {
const bytes = new TextEncoder().encode(str);
let binary = '';
bytes.forEach(b => { binary += String.fromCharCode(b); });
return btoa(binary);
}
function fromBase64(b64) {
const binary = atob(b64);
const bytes = Uint8Array.from(binary, c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
toBase64('Harga 10€ 🚀'); // aman
fromBase64(toBase64('Halo dunia')); // "Halo dunia"
Untuk mengubah hasilnya menjadi base64url, ganti karakternya dan buang padding:
const toBase64Url = s => toBase64(s)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
Di Node.js, cara paling praktis adalah Buffer, yang sudah menangani UTF-8 dan base64url secara bawaan:
Buffer.from('Harga 10€', 'utf8').toString('base64');
Buffer.from('SGVsbG8=', 'base64').toString('utf8'); // "Hello"
Buffer.from('data', 'utf8').toString('base64url');
Beberapa browser modern juga mulai mendukung Uint8Array.prototype.toBase64() dan Uint8Array.fromBase64(). Karena dukungannya belum merata, cek kompatibilitas sebelum mengandalkannya di produksi.
Base64 di PHP
PHP memakai base64_encode() dan base64_decode(). Karena string PHP adalah deretan byte, tidak ada masalah UTF-8 seperti di btoa():
<?php
$encoded = base64_encode('Harga 10€');
echo $encoded; // SGFyZ2EgMTDigqw=
echo base64_decode($encoded); // Harga 10€
// Mode strict: return false jika ada karakter tidak valid
$hasil = base64_decode('@@@', true);
var_dump($hasil); // bool(false)
// Encode file gambar menjadi data URI
$path = __DIR__ . '/logo.png';
$dataUri = 'data:image/png;base64,' . base64_encode(file_get_contents($path));
Selalu gunakan parameter kedua true saat men-decode input dari pengguna. Tanpa mode strict, base64_decode() diam-diam membuang karakter tidak valid dan mengembalikan data sampah, yang bisa menyembunyikan bug.
PHP tidak punya fungsi base64url bawaan, tetapi mudah dibuat sendiri:
<?php
function base64url_encode(string $data): string {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode(string $data): string|false {
$data = strtr($data, '-_', '+/');
$data .= str_repeat('=', (4 - strlen($data) % 4) % 4);
return base64_decode($data, true);
}
Kesalahan umum saat memakai Base64
- Menganggapnya sebagai pengamanan. Menyembunyikan API key dengan Base64 di kode frontend tidak melindungi apa pun.
- Memakai
btoa()untuk teks non-ASCII. GunakanTextEncoderterlebih dahulu. - Mencampur Base64 standar dan base64url. Hasil decode menjadi salah atau gagal tanpa pesan jelas.
- Menaruh Base64 standar di URL tanpa di-encode. Tanda
+berubah menjadi spasi di sisi server. Gunakan base64url atau lakukan URL encoding. - Menyimpan file besar sebagai Base64 di database. Ukuran naik sekitar 33% dan query menjadi lambat.
- Lupa spasi atau newline. Copy-paste dari email sering membawa baris baru; bersihkan dulu sebelum decode strict.
Checklist singkat
- Base64 = encoding, bukan enkripsi. Data rahasia butuh enkripsi atau hashing.
- 3 byte menjadi 4 karakter; ukuran bertambah sekitar 33%.
=adalah padding; panjang Base64 standar selalu kelipatan 4.- Pakai base64url untuk URL, nama file, dan token.
- Di browser, ubah teks ke UTF-8 dengan
TextEncodersebelumbtoa(). - Di PHP, decode input pengguna dengan
base64_decode($s, true).
FAQ
Apakah Base64 aman untuk menyimpan password?
Tidak. Base64 bisa dikembalikan dalam satu langkah tanpa kunci. Untuk password, gunakan hashing khusus password seperti bcrypt atau Argon2, misalnya lewat password_hash() di PHP atau Hash::make() di Laravel.
Kenapa hasil Base64 saya diakhiri dua tanda sama dengan?
Karena panjang data asli menyisakan 1 byte setelah dibagi 3. Tanda == adalah padding yang menandakan dua karakter terakhir hanya berisi bit pengisi. Itu normal, bukan error.
Apa beda Base64 dan base64url?
base64url mengganti + menjadi - dan / menjadi _, dan biasanya tanpa padding, agar aman dipakai di URL dan nama file. Isinya sama; hanya alfabetnya yang sedikit berbeda.
Berapa besar ukuran file setelah di-encode Base64?
Kira-kira 4/3 dari ukuran asli, atau naik sekitar 33%. Rumusnya 4 × ceil(n / 3) karakter untuk data sepanjang n byte, belum termasuk baris baru jika formatnya MIME.
Kenapa btoa() error di karakter tertentu?
btoa() hanya menerima karakter dengan kode 0–255. Karakter seperti € atau emoji berada di luar rentang itu, sehingga perlu diubah dulu menjadi byte UTF-8 dengan TextEncoder.