Basis64: Apa peningkatan terburuk dalam penggunaan ruang?

167

Jika server menerima string base64 dan ingin memeriksa panjangnya sebelum mengonversi ,, katakan itu ingin selalu mengizinkan array byte terakhir menjadi 16KB. Seberapa besar susunan byte 16KB bila dikonversi ke string Base64 (dengan asumsi satu byte per karakter)?

Bryan Field
sumber

Jawaban:

243

Base64 mengkodekan setiap set tiga byte menjadi empat byte. Selain itu output empuk untuk selalu menjadi kelipatan empat.

Ini berarti bahwa ukuran representasi basis-64 dari string berukuran n adalah:

ceil(n / 3) * 4

Jadi, untuk larik 16kB, representasi basis-64 akan menjadi ceil (16 * 1024/3) * 4 = 21848 byte panjang ~ = 21,8 kB.

Sebuah kasar pendekatan akan bahwa ukuran data yang meningkat menjadi 4/3 dari aslinya.

R. Martinho Fernandes
sumber
Apakah kita perlu menambahkan 2 panjangnya atau tidak?
vIceBerg
@vIceBerg, Itu tergantung pada apakah Anda menggunakan ceildengan floatangka, atau hanya intangka. (dan tidak ceil)
Lapangan Bryan
7
Saya kira cara yang lebih sederhana untuk menambahkan ini adalah Anda menambahkan 1/3 dari ukuran aslinya.
mvmn
1
Dalam contoh yang Anda usulkan, menunjukkan hasil dalam urutan pengukuran yang sama akan meningkatkan kualitas jawaban (21,3 KB, bukannya 21848 Bytes).
Ivan De Paz Centeno
36

Dari Wikipedia

Perhatikan bahwa diberi input n byte, output akan menjadi (n + 2 - ((n + 2)% 3)) / 3 * 4 byte panjang, sehingga jumlah byte keluaran per byte input konvergen ke 4/3 atau 1,33333 untuk besar n.

Jadi 16kb * 4/3 memberikan sangat sedikit lebih dari 21,3 'kb, atau 21848 byte, tepatnya.

Semoga ini membantu

Biner Terburuk
sumber
11

16kb adalah 131.072 bit. Base64 mengemas buffer 24-bit menjadi empat karakter masing-masing 6-bit, sehingga Anda akan memiliki 5.462 * 4 = 21.848 byte.

Chris Heald
sumber
5

Karena pertanyaannya adalah tentang kemungkinan peningkatan terburuk, saya harus menambahkan bahwa biasanya ada jeda baris sekitar 80 karakter. Ini berarti bahwa jika Anda menyimpan data yang disandikan base64 ke dalam file teks pada Windows itu akan menambah 2 byte, di Linux 1 byte untuk setiap baris.

Peningkatan dari pengkodean aktual telah dijelaskan di atas.

Zsolt Sky
sumber
3
Bukankah kasus ekstrim bahwa 1 byte sumber menjadi 4 basis64 byte, jadi peningkatan 4x? Setiap materi sumber yang lebih lama mendapat rasio yang lebih baik sampai, seperti yang orang lain katakan, mendekati asimtotik 1,333 ...
Olie
1

Ini referensi masa depan untuk saya sendiri. Karena pertanyaannya adalah yang terburuk kasus , kita harus mempertimbangkan jeda baris. Sementara RFC 1421 mendefinisikan panjang garis maksimum menjadi 64 char, RFC 2045 (MIME) menyatakan akan ada 76 char dalam satu baris paling banyak.

Yang terakhir adalah apa yang telah diimplementasikan oleh perpustakaan C #. Jadi di lingkungan Windows di mana satu baris adalah 2 karakter (\ r \ n), kita mendapatkan ini:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Catatan: Lantai adalah karena selama pengujian saya dengan C #, jika baris terakhir berakhir tepat pada 76 karakter, tidak ada garis-istirahat yang mengikuti.

Saya bisa membuktikannya dengan menjalankan kode berikut:

byte[] bytes = new byte[16 * 1024];
Console.WriteLine(Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks).Length);

Jawaban untuk 16 kBytes dikodekan ke base64 dengan garis 76-char: 22422 karakter

Asumsikan di Linux itu akan Length = Floor(Ceiling(N/3) * 4 * 77 / 76)tetapi saya belum sempat mengujinya pada .NET core saya.

Lionet Chen
sumber