Base64: Що є найгіршим можливим збільшенням використання простору?


168

Якщо сервер отримав рядок base64 і хотів перевірити його довжину перед перетворенням,, скажіть, він хотів завжди дозволяти остаточному байтовому масиву бути 16 КБ. Наскільки великим може стати байтовий масив розміром 16 КБ при перетворенні на рядок Base64 (припускаючи один байт на символ)?

Відповіді:


245

Base64 кодує кожен набір з трьох байтів на чотири байти. Окрім того, вихід має прокладений, щоб він завжди був кратним чотирьом.

Це означає, що розмір представлення base-64 рядка розміром n дорівнює:

ceil(n / 3) * 4

Так, для масиву 16 кБ представленням бази-64 буде ceil (16 * 1024/3) * 4 = 21848 байт довгою ~ = 21,8 кБ.

Грубе наближення було б , що розмір даних збільшується до 4/3 оригіналу.


Потрібно нам додати 2 в довжину чи ні?
vIceBerg

@vIceBerg, Це залежить від того, чи використовуєте ви ceilз floatчислами, або просто intчислами. (та ні ceil)
Брайан Філд

7
Я думаю, найпростіший спосіб поставити це - ви додасте 1/3 оригінального розміру.
mvmn

1
У запропонованому вами прикладі показ результату в тому ж порядку вимірювань трохи збільшить якість відповіді (21,3 Кб замість 21848 байт).
Іван Де Пас Сентено

36

З Вікіпедії

Зверніть увагу, що з урахуванням n байтів, вихід буде довгим (n + 2 - ((n + 2)% 3)) / 3 * 4 байтів, так що кількість вихідних байтів на один вхідний байт збільшиться до 4/3 або 1,333333 для великих n.

Тож 16kb * 4/3 дає дуже мало понад 21,3 'kb, або 21848 байт, якщо бути точним.

Сподіваюся, це допомагає


11

16 кб - 131 072 біт. Base64 пакує 24-бітні буфери в чотири 6-бітових символів за штуку, тож у вас буде 5 462 * 4 = 21 848 байт.


5

Оскільки питання стосувалося найгіршого можливого збільшення, я мушу додати, що зазвичай буває розрив рядків приблизно на кожні 80 символів. Це означає, що якщо ви зберігаєте закодовані дані base64 у текстовому файлі в Windows, він додасть 2 байти, для Linux 1 байт для кожного рядка.

Збільшення від фактичного кодування описано вище.


3
Хіба не крайній випадок, що один байт джерела стає 4 базовими 64 байтами, тож в 4 рази збільшується? Будь-який довший вихідний матеріал набуває кращого співвідношення до тих пір, як, як казали інші, він асимптотично не наближається до 1.333 ...
Olie

1

Це майбутня довідка для себе. Оскільки питання йде про найгірший випадок, ми повинні враховувати перерви у рядках. У той час як RFC 1421 визначає максимальну довжину лінії до 64 знаків, RFC 2045 (MIME) стверджує, що в одному рядку може бути не більше 76 знаків.

Останнє - це те, що впроваджена бібліотека C #. Отже, в середовищі Windows, де розрив рядка становить 2 знаки (\ r \ n), ми отримуємо це:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Примітка. Підлогове покриття полягає в тому, що під час мого тестування на C #, якщо останній рядок закінчується рівно на 76 символів, жодного розриву рядків не слід.

Я можу це довести, виконавши наступний код:

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

Відповідь на 16 кБайт, закодованих до base64, 76-знаковими лініями: 22422 символів

Припустимо, в Linux це було б, Length = Floor(Ceiling(N/3) * 4 * 77 / 76)але я ще не обійшов його перевірити на своєму ядрі .NET.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.