Alat pembangun · Pengekod & penyahkod Base64
Apakah maksud atob dan btoa, dan mengapa mereka sahaja memahami bahasa Latin-1
· Latar belakang
asas64 javascript unicode
atob dan btoa tarikh dari Netscape dan nama itu bermaksud 'ASCII kepada binari' dan 'perduaan kepada ASCII'. Siaran ini merangkumi dari mana asalnya, cara piawaian WHATWG mentakrifkannya dan sebab mereka tidak pernah mempelajari Unicode.
Nama fungsi yang berbunyi seperti kesilapan menaip — kekeliruan yang disebabkan oleh nama dan jawapan satu baris
atob dan btoa ialah JavaScript fungsi terbina dalam yang diperkenalkan dalam Netscape pada tahun 1990-an. Nama-nama tersebut adalah singkatan: btoa bermaksud binari kepada ASCII dan atob bermaksud ASCII kepada binari. Nama tersebut mencerminkan umur dan reka bentuknya: ia dibina apabila binari bermaksud rentetan nilai bait (0-255) dan bukannya Uint8Array atau Buffer yang lebih moden. Mnemonik yang sering diberikan untuk nama adalah kurang penting daripada kontrak yang boleh diperhatikan: satu fungsi memetakan rentetan binari ke Base64 dan yang lain membalikkannya. Repositori ini tidak mendokumenkan keputusan penamaan asal, jadi artikel itu mengelak daripada mempersembahkan cerita rakyat sebagai sejarah pelayar bersumber.
Fungsi mengharapkan rentetan binari: setiap unit kod aksara mestilah dalam julat 0-255, mewakili satu bait. Jika anda menghantar aksara dengan unit kod di atas 255 (seperti emoji atau huruf beraksen dari luar Latin-1), fungsi itu membuang InvalidCharacterError atau secara senyap menghasilkan output yang salah. btoa (perduaan kepada ASCII) mengekod rentetan binari kepada base64.
Apa yang dicadangkan oleh nama dan apa yang sebenarnya dibuktikan oleh kontrak rentetan bait
Input mestilah rentetan dengan setiap aksara ialah bait (unit kod 0-255). btoa(hello) mengekod ASCII bait sebagai base64 dan mengembalikan aGVsbG8=. btoa dengan huruf e-acute nampaknya berfungsi kerana huruf Latin-1 e-acute (U+00E9) yang diprakomposisi mempunyai unit kod 233, yang berada dalam 0-255. Walau bagaimanapun, btoa mengekodnya sebagai bait tunggal, 0xE9, bukan UTF-8 bait 0xC3 0xA9 yang sepatutnya dihasilkan oleh e-acute. Sebelum tatasusunan ditaip menjadi bekas bait biasa, JavaScript API menggunakan rentetan yang unit kodnya bermaksud bait. Model itu kekal kelihatan kerana btoa menolak unit kod di atas 255. Kronologi produk yang tepat tidak ditentukan oleh fail ini; sempadan kegagalan ditetapkan oleh ujian boleh laku.
Rasuah senyap ini lebih berbahaya daripada kesilapan: hasilnya kelihatan baik tetapi salah. atob (ASCII kepada binari) menyahkod base64 kembali kepada rentetan binari. atob(aGVsbG8=) membalas helo. Output ialah rentetan binari di mana unit kod setiap aksara ialah 0-255, mewakili satu bait. Jika anda ingin menukar ini kepada teks Unicode yang betul, anda perlu mentafsirkan bait sebagai UTF-8 dan menyahkodnya dengan TextDecoder.
Model rentetan binari warisan — gelagat yang boleh diperhatikan tanpa tuntutan sejarah pelayar yang tidak disahkan
Untuk ASCII, langkah tambahan ini tidak diperlukan (ASCII ialah subset UTF-8), tetapi untuk mana-mana bait bukan ASCII, ia adalah penting. atob tidak melakukan tafsiran itu; ia mengembalikan bait mentah sebagai rentetan binari.
Piawaian WHATWG (standard hidup untuk API web) mentakrifkan atob dan btoa dalam spesifikasi HTML. Takrifan termasuk algoritma penyahkod asas64 yang memaafkan untuk atob: ia melangkau ruang kosong dan menerima padding yang tiada, menjadikan base64 dunia sebenar (termasuk base64 yang dibalut MIME dengan pemisah baris) boleh dinyahkod. ToolAcre menormalkan ruang kosong, URL-tanda baca selamat dan tiada padding sebelum memanggil penyahkod pelayar. Ia kemudian menyalin unit kod yang dikembalikan ke dalam Uint8Array dan menggunakan penyahkod UTF-8 yang membawa maut. Gabungan itu memisahkan sintaks Base64 yang memaafkan daripada tafsiran teks yang ketat.
Tingkah laku semasa dalam pelaksanaan ini — memaafkan normalisasi abjad dan penyahkodan teks UTF-8 yang ketat
Tandatangan fungsi tidak berubah, tetapi definisi piawai adalah kuasa untuk apa yang fungsi itu lakukan. Mengapa atob dan btoa sahaja menerima bahasa Latin-1? Kerana apabila ia direka pada tahun 1990-an, JavaScript tidak mempunyai cara untuk mewakili bait secara langsung (tiada Uint8Array atau ArrayBuffer). Satu-satunya cara untuk menghantar bait kepada fungsi adalah sebagai rentetan di mana setiap aksara mewakili satu bait.
Ini dipanggil rentetan binari dan mengelirukan mengikut piawaian moden. Rentetan JavaScript ialah teks Unikod, bukan urutan bait. Reka bentuk menggabungkan dua: rentetan di mana setiap unit kod ialah 0-255 ialah rentetan binari. Penamaan mencerminkan era: ASCII dalam btoa secara literal bermaksud tujuh bit untuk teks ASCII, tetapi pelaksanaannya menerima sebarang bait (0-255). Menambah mod Unicode terus ke btoa akan mengubah kontrak rentetan bait dan keserasian risiko yang telah lama wujud. Sumber yang disemak sebaliknya mengarang TextEncoder sebelum pengekodan. Artikel ini boleh mengesahkan komposisi itu; ia mengetepikan dakwaan tentang motif jawatankuasa piawai yang tidak direkodkan dalam repositori.
Contoh yang berjaya: mengesan forgiving-base64 pada rentetan dengan ruang dan padding yang tiada — perkara yang diterima oleh atob yang ditolak oleh penyahkod yang ketat
Alternatif moden mengelakkan model rentetan binari. Pengekodan API menyediakan TextEncoder untuk menukar teks kepada UTF-8 bait dan TextDecoder untuk menukar UTF-8 bait kembali kepada teks.
Pengekodan dan penyahkodan Base64 kini ditentukan dalam spesifikasi HTML untuk kedua-dua rentetan (atob dan btoa) dan tatasusunan ditaip. Alat pengekod & penyahkod Base64 menggunakan TextEncoder dan TextDecoder di sekeliling atob dan btoa, jadi anda boleh mengekod dan menyahkod teks Unicode dengan selamat tanpa pengehadan Latin-1. Nilai jarak atau tidak empuk berjaya kerana penormalan mengalih keluar ruang kosong dan memulihkan panjang blok yang diperlukan. Nilai yang panjangnya dibersihkan meninggalkan baki satu ditolak sebelum atob. Perbezaan ini menunjukkan maksud "memaafkan" di sini: pemformatan boleh pulih diterima, input yang mustahil secara struktur tidak diterima.
Piawaian yang lebih baharu berfungsi pada Base64 untuk tatasusunan ditaip — diterangkan secara kualitatif, dengan nota untuk menyemak sokongan pelayar semasa
Mengendalikan Unicode dengan btoa memerlukan teks pengekodan kepada UTF-8 bait terlebih dahulu. Penyelesaian lama ialah btoa(unescape(encodeURIComponent(text))), yang mengelirukan tetapi berfungsi: encodeURIComponent percent-encodes UTF-8 bait, unescape menukarkan triplet kembali kepada aksara dan btoa mengekod rentetan binari yang terhasil. Ini berfungsi tetapi bergantung pada fungsi yang tidak digunakan dan sukar dibaca. Kod moden harus menggunakan TextEncoder(text).map(byte => String.fromCharCode(bait)) diikuti dengan btoa, atau lebih baik, tukar terus kepada Uint8Array dan gunakan Pengekodan API.
Atob tidak secara automatik memberi anda teks; ia memberi anda binari. atob(Y2Fmw6kg8J+YgA==) mengembalikan rentetan perduaan yang mengandungi bait teks berkod UTF-8 dengan aksen caf dan emoji. Untuk memulihkan teks, tukar rentetan binari kepada Uint8Array dan hantarkannya kepada TextDecoder(utf-8). Alat pengekod & penyahkod Base64 melakukan ini secara automatik: anda menampal teks, ia mengekodkannya kepada UTF-8 bait, kemudian ke base64. API Base64 tatasusunan taip sedang berkembang merentas pelayar, tetapi sumber ini tidak menggunakannya. Bergantung pada satu memerlukan semakan keserasian semasa dan pelan sandaran. Penukaran bait-bait eksplisit ToolAcre kekal boleh diperiksa dan dilindungi oleh suite ujiannya yang sedia ada.
Alternatif tatasusunan taip sedang berkembang — sahkan sokongan pelayar semasa sebelum bergantung padanya
Anda menampal base64, ia menyahkod kepada UTF-8 bait, kemudian kepada teks. Langkah rentetan binari perantaraan disembunyikan kerana ia merupakan perincian pelaksanaan API 1990-an. Memahami atob dan btoa berguna untuk menyahpepijat kod warisan atau bekerja dengan API lama yang memberikan anda rentetan binari. Kebanyakan kod baharu harus mengelakkan model rentetan binari sepenuhnya.
Jika anda perlu mengekod atau menyahkod base64, alat pengekod & penyahkod Base64 mengendalikan Unicode dengan betul. Jika anda sedang membina API, terima Uint8Array atau paparan tatasusunan bertaip, atau dokumen dengan jelas sama ada base64 anda ialah UTF-8 atau Latin-1. Apabila menyemak kod yang menggunakan btoa dengan teks bukan ASCII tanpa TextEncoder, ia adalah pepijat: output mengekod bait yang salah. Penampan Nod dan masa jalan bukan pelayar mentakrifkan API dan peraturan penerimaan yang berbeza. Mereka sengaja dikecualikan. Tuntutan dalam artikel ini melibatkan primitif pelayar dan pembungkus yang dilaksanakan dalam apps/dev, bukan setiap fungsi bernama atob atau btoa dalam setiap persekitaran.
Bawa pulang: dua tahun 1990-an berfungsi dengan kontrak rentetan bait — cara pengekod & penyahkod Base64 melakukan langkah UTF-8 di sekelilingnya supaya aksen, CJK dan emoji pergi-balik
Nama atob dan btoa adalah artifak pelik pengkomputeran tahun 1990-an. Penamaan moden ialah base64Encode dan base64Decode, dan API akan menerima Uint8Array atau rentetan dengan pengisytiharan pengekodan eksplisit. Tetapi atob dan btoa berterusan dalam pelayar untuk keserasian ke belakang. Memahami maksudnya (dan perkara yang tidak boleh mereka lakukan) membantu anda mengelakkan rasuah senyap apabila mengekod teks Unicode.
Alat pengekod & penyahkod Base64 merapatkan jurang: ia bercakap UTF-8 dan bahasa base64 yang diperlukan oleh kod moden. Corak teguh adalah gubahan: mengekod teks kepada UTF-8 bait, tukar bait kepada kontrak rentetan binari, kemudian panggil btoa; terbalikkan langkah-langkah di sekeliling atob. Cuba loghat, CJK aksara dan emoji, kemudian minta teks yang dinyahkod itu sepadan dengan setiap titik kod asal.