Enkode / Dekode Base91

Konversikan teks atau byte biner dengan basE91: 13 bit input per 2 karakter yang dapat dicetak, menjadikannya encoding dapat-dicetak paling padat dalam penggunaan sehari-hari — overhead sekitar 23% dibanding 33% milik Base64. Teks diproses sebagai byte UTF-8; mode byte heksadesimal tersedia untuk data biner. Juga: Base64 | Base32 / Base58 | Ascii85.
Semua pemrosesan berlangsung secara lokal di browser — data tidak pernah diunggah ke server mana pun.

Belum pernah mendengar Base91? Apa itu Base91 — dijelaskan dengan bahasa sederhana (dengan contoh yang dikerjakan, alfabet, dan jebakannya).
Cara kerja: Input diubah menjadi byte, lalu dikemas ke dalam grup 13 bit yang masing-masing menjadi dua karakter, dengan satu grup 14 bit di setiap tempat bentuk pendeknya ambigu.
Input berupa:
Cara kerja: Spasi diabaikan, dan setiap karakter dicari dalam alfabet yang dicetak lebih jauh di halaman ini. Karakter yang tidak dikenal dilaporkan beserta posisinya.
Output sebagai:
Ctrl+Enter di input menjalankan mode yang aktif.
Pilih Enkode atau Dekode lalu klik tombol aksinya. Uji mandiri menjalankan 130 putaran enkode/dekode dan melaporkan jumlahnya di sini.
Alfabet, dicetak lengkap: Base91 tidak memiliki badan standar di belakangnya, sehingga alfabetnya tidak dijamin lintas implementasi. Halaman ini memakai alfabet implementasi referensi, dan setiap nilai di bawah dihasilkan dengan tepat 91 karakter yang tercantum di tabel.
Sel hijau adalah karakter yang aman untuk berada dalam teks HTML atau query URL; yang oranye harus di-escape atau di-persen-encode (lihat catatan di bawah tabel).
Sel hijau adalah karakter yang aman untuk berada dalam teks HTML atau query URL; yang oranye harus di-escape atau di-persen-encode (lihat catatan di bawah tabel).
Ukuran yang diukur pada input 92 byte yang sama:
Jumlah karakter yang diukur di sini pada string. Base91 menang karena 912 = 8281 mencakup 8192 nilai dari 13 bit, sedangkan Base64 menghabiskan 4 karakter hanya untuk 24 bit.
Apa itu Base91?

Base91 adalah cara menulis byte sembarang hanya dengan karakter ASCII yang dapat dicetak, pekerjaan yang sama dengan Base64, tetapi memuat lebih banyak bit ke setiap karakter. Alih-alih memotong input menjadi grup 6 bit dan mencetak satu karakter per grup, ia mengumpulkan bit hingga memiliki setidaknya 13, lalu mencetak dua karakter yang bersama-sama menamai nilai dari 13 (atau 14) bit tersebut.

Dua karakter dari alfabet berisi 91 dapat menamai 91 × 91 = 8281 nilai berbeda, dan 213 = 8192, sehingga dua karakter selalu punya ruang untuk 13 bit — dengan 89 nilai sisa. Itulah seluruh trik-nya: 13 bit per 2 karakter adalah 6,5 bit per karakter, dibanding 6 milik Base64, dan itu memberi overhead sekitar 23% alih-alih 33%.

Versi 30 detik: test menjadi fPNKd, dan Hello, World! menjadi >OwJh>}AQ;r@@Y?F. Dekode adalah kebalikan persisnya, dan memerlukan alfabet 91 karakter yang sama — alfabet berbeda menghasilkan output yang berbeda dari byte yang sama.
Dari mana asal 13 dan 14 bit

91 × 91 = 8281 nilai dapat dinamai oleh sepasang karakter, lebih banyak daripada 213 = 8192 tetapi kurang dari 214 = 16384. Jadi sepasang karakter selalu dapat memuat 13 bit, dan terkadang 14. Encoder mencoba 13 bit lebih dulu: jika nilai 13 bit lebih besar dari 88, ia mencetak nilai itu sebagai dua karakter; jika tidak, ia mengambil bit ke-14 dan mencetak nilai 14 bit yang dihasilkan.

Batas di 88 bukan sembarang. Nilai terbesar yang dapat dinamai dua karakter adalah 90 + 91 × 90 = 8280, dan 8192 + 89 = 8281 sudah melampauinya. Jadi tidak ada grup 14 bit yang bisa memiliki jendela 13 bit rendah sebesar 89 atau lebih, yang berarti decoder dapat membedakan kedua kasus hanya dengan melihat nilainya sendiri:

Yang dilihat decoderBit yang dikonsumsiAlasan
value & 8191 adalah 89 hingga 819113 bitNilai 89 ke atas hanya dapat berasal dari cabang 13 bit, karena grup 14 bit dengan jendela 13 bit rendah setinggi itu harus setidaknya 8281 — yang tidak dapat dinamai pasangan karakter mana pun.
value & 8191 adalah 0 hingga 8814 bitEncoder hanya beralih ke 14 bit ketika pembacaan 13 bit bernilai 88 atau kurang, sehingga cabang ini adalah cadangan dan tidak ada yang lain.

Sisa apa pun di akhir — dari 1 hingga 13 bit — dicetak sebagai satu karakter, ditambah karakter kedua jika sisanya memang membutuhkan lebih dari 7 bit. Itulah sebabnya panjang encoded bertambah dalam langkah dua karakter dan kadang berakhir pada jumlah ganjil.

Alfabet, dan tiga karakter yang dibuangnya

ASCII yang dapat dicetak memuat 94 karakter, dari ! (0x21) hingga ~ (0x7E). Base91 memakai 91 di antaranya, dan tiga yang ditinggalkan adalah tanda hubung -, apostrof ', dan garis miring terbalik \. Huruf, digit, dan hampir semua tanda baca berada dalam alfabet tepat sekali, dengan urutan yang ditunjukkan di tabel di atas; karakter yang dapat dicetak ke-92 hingga ke-94 memang tidak dapat dialamatkan.

Karena alfabetnya berurutan tetap, karakter untuk sebuah nilai adalah pencarian, bukan rumus. Dua implementasi yang mengurutkan alfabetnya berbeda sama-sama disebut "Base91" dan tidak dapat saling membaca output masing-masing, yang merupakan sumber hasil membingungkan paling umum. Halaman ini mencetak alfabetnya sehingga output selalu dapat ditelusuri kembali ke sana.

Base91 dibandingkan dengan encoding dapat-dicetak lainnya
EncodingBit per karakterUkuran dibanding inputCatatan
Base16 (hex)4200%Dua karakter per byte, sangat mudah dibaca, tanpa alfabet untuk dicari.
Base325160%Tidak peka huruf besar-kecil dan aman untuk didiktekan, tetapi paling boros dalam kelompoknya.
Base58~5,86~137%Dipilih untuk alamat, bukan kepadatan: menghindari karakter yang mirip.
Base646133%Default di mana-mana: 4 karakter per 3 byte, dengan 6 bit yang tidak terpakai pada karakter terakhir terbuang.
Ascii85 / Base856,4125%5 karakter per 4 byte, tidak memerlukan tabel pencarian, tetapi membagi dengan 85 — lihat konverter Ascii85.
Base91~6,5~123%Yang paling padat di antara ini: 13 bit per 2 karakter, dengan harga grup 14 bit sesekali.

Persentase adalah biaya asimtotik setiap encoding, dibulatkan; jumlah karakter yang diukur untuk satu input nyata 92 byte ada di tabel di bagian atas halaman ini. Base91 mendekati yang terbaik yang dapat dicapai encoding mana pun dengan ASCII yang dapat dicetak: 7 bit per karakter berarti memakai 128 karakter berbeda, yang tidak dapat disediakan rentang yang dapat dicetak.

Apa yang bukan Base91
  • Bukan standar. Tidak ada RFC. Implementasi referensinya adalah basE91 0.6.0 oleh Joachim Henke, dirilis di bawah lisensi BSD 3 klausul; "Base91" juga dipakai untuk alfabet yang bukan ini.
  • Bukan enkripsi. Setiap karakter adalah penataan ulang lurus dari bit input, dan siapa pun yang memiliki alfabetnya dapat membalikkannya dalam satu langkah.
  • Tidak aman untuk URL. Alfabetnya memuat #, %, &, /, ?, dan ", yang semuanya mengubah makna dalam URL, sehingga output Base91 harus di-persen-encode sebelum masuk ke query string.
  • Tidak aman untuk HTML. Alfabetnya juga memuat <, >, &, dan ", sehingga string Base91 yang ditempatkan dalam markup harus di-escape dengan konverter entitas HTML.
  • Panjang tidak tetap. Panjang output bergantung pada pola bit, bukan hanya jumlah byte, sehingga dua input berukuran sama dapat dicetak berbeda satu karakter.
Jebakan yang benar-benar menyulitkan
  • Alfabet di halaman ini adalah alfabet referensi. Jika alat lain menghasilkan output berbeda untuk input yang sama, bandingkan alfabetnya sebelum menganggap salah satu sisi rusak. Ke-91 karakter harus muncul dengan urutan yang sama.
  • Satu karakter yang salah dapat mengubah seluruh ekor. Batas grup ditentukan oleh nilai-nilai sebelumnya, sehingga suntingan di awal string menggeser semua yang sesudahnya, dan ekor didekode hanya dengan bit sisa dari grup terakhir.
  • Panjang output yang ganjil itu normal. Itu tidak berarti string terpotong; grup terakhir mencetak satu karakter ketika nilai sisanya muat dalam 7 bit atau kurang.
  • Contoh yang dipublikasikan dapat membawa baris baru yang tidak diketik. Perintah shell yang menambahkan akhir baris adalah alasan umum mengapa nilai Base91 yang terkenal satu karakter lebih panjang daripada teks yang sama di sini: echo "Hello, World!" memberi encoder 14 byte dan mencetak >OwJh>}AQ;r@@Y?FF, sedangkan 13 byte teksnya saja mencetak >OwJh>}AQ;r@@Y?F. Keduanya benar, untuk jumlah byte yang berbeda, dan jumlah di bawah kotak output menunjukkan yang mana yang sedang dipegang.
  • Mendekode data biner sebagai teks tidak akan berhasil. Jika byte hasil dekode bukan UTF-8 yang valid, tidak ada teks yang masuk akal untuk ditampilkan, dan itulah fungsi mode output heksadesimal.
Jawaban singkat

“Mengapa halaman ini menampilkan nilai yang berbeda satu karakter dari alat Base91 lain?”

Hampir selalu alfabet yang berbeda. Penyebab kedua paling umum adalah alat yang hanya memakai cabang 13 bit dan tidak pernah cadangan 14 bit; varian itu lebih kecil dalam kode tetapi menghasilkan output yang berbeda dari algoritma referensi yang dipakai di sini.

Ada juga satu kasus pasti yang dapat diselesaikan dengan menghitung byte, dan ini menjelaskan contoh yang paling banyak dikutip: baris baru di akhir. Sebagian besar vektor yang dipublikasikan dihasilkan oleh perintah shell, dan shell menambahkan akhir baris yang menyelesaikan baris itu. 13 byte Hello, World! dicetak sebagai 16 karakter di sini, sedangkan 14 byte Hello, World! diikuti baris baru dicetak sebagai 17 karakter >OwJh>}AQ;r@@Y?FF. Tempel salah satu nilai ke Dekode: halaman ini melaporkan jumlah byte, sehingga kedua pembacaan dapat dibedakan tanpa perdebatan. Tombol Contoh memuat nilai yang sesuai dengan pembaca yang dipakai, dan mengikuti sakelar Enkode / Dekode serta pemilih Input berupa / Output sebagai: pembaca teks mendapat nilai 16 karakter, pembaca heksadesimal mendapat nilai 17 karakter dengan byte 0A di akhirnya yang terlihat jelas, dan encoder mendapat teks untuk dienkode alih-alih string Base91.

“Apakah Base91 lebih kecil daripada Base64?”

Ya, sekitar 8% dari ukuran encoded: 13 bit per 2 karakter dibanding 6 bit per karakter. Pada 92 byte teks, Base64 mencetak 124 karakter dan Base91 mencetak 114.

“Dapatkah ini didekode dengan decoder Base64, atau sebaliknya?”

Tidak. Alfabetnya tumpang tindih pada huruf dan digit, sehingga decoder Base64 akan menerima string Base91 sebagai karakter "valid" dan menghasilkan sampah yang diam-diam. Keduanya hanya sepakat pada bentuk skemanya.

“Apakah output berakhir dengan padding seperti Base64?”

Tidak. Base91 tidak memiliki karakter padding sama sekali: bit sisa di akhir dicetak sebagai grup terakhir, sehingga tidak ada yang perlu ditambahkan atau dihapus.

“Bagaimana memastikan hasil di halaman ini benar?”

Tekan Uji mandiri 0 hingga 64 byte. Ini mengenkode dan mendekode 130 pola byte yang mencakup setiap panjang tempat pemisahan 13 dan 14 bit berubah, lalu membandingkan byte yang kembali dengan byte yang masuk. Vektor pada tombol Contoh juga dicocokkan silang dengan implementasi kedua yang ditulis untuk perkakas uji situs ini.

Standar dan kredit

Halaman ini mengimplementasikan algoritma implementasi referensi basE91 (versi 0.6.0) oleh Joachim Henke, didistribusikan di bawah lisensi BSD 3 klausul, dengan alfabet yang dicetak di atas. Dekode menerima dan mengabaikan spasi, seperti alat referensinya.

Halaman teks ini ditulis untuk situs ini; algoritmanya tidak disalin dari mana pun. Nilai tombol Contoh adalah satu contoh yang disertakan dalam paket referensi (ditandai "contoh referensi") ditambah nilai yang dihasilkan oleh implementasi kedua yang independen dan disimpan dalam perkakas uji situs ini (ditandai "pemeriksaan silang").