UTF-8 menulis titik kode menjadi satu sampai empat byte. Seluruh huruf ASCII tetap satu byte dengan nilai yang sama seperti dulu, sehingga berkas ASCII lama otomatis sah sebagai UTF-8. Karakter di luar ASCII memakai dua byte atau lebih, dan byte-byte itu selalu bernilai 128 ke atas. Aturan lengkapnya ditetapkan RFC 3629.
Mojibake muncul ketika byte UTF-8 dibaca memakai encoding satu byte seperti cp1252 atau latin-1. Program itu tidak menolak, karena setiap byte punya arti di tabelnya sendiri. Hasilnya satu huruf beraksen berubah menjadi dua atau tiga huruf aneh, dan datanya tetap utuh di dalam berkas — yang salah adalah cara membacanya.
| Maksud aslinya | Byte UTF-8 | Tampilan saat dibaca cp1252 |
|---|---|---|
| é | C3 A9 | é |
| – (tanda pisah en) | E2 80 93 | – |
| — (tanda pisah em) | E2 80 94 | — |
| ’ (apostrof miring) | E2 80 99 | ’ |
rusak = "André Niño"
benar = rusak.encode("cp1252").decode("utf-8")
print(benar) # André NiñoNama orang paling sering jadi korban karena di sanalah aksara di luar ASCII berkumpul: André, Nguyễn, Saoirse, sampai apostrof miring hasil koreksi otomatis pengolah kata. Perbaikan di atas hanya bekerja sekali; kalau berkas yang sudah rusak disimpan ulang sebagai UTF-8, kerusakannya ikut tersimpan dan lapisannya bertambah.