Base64: Какое худшее возможное увеличение использования пространства?

168

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

Брайан Филд
источник

Ответы:

245

Base64 кодирует каждый набор из трех байтов в четыре байта. Кроме того, вывод дополняется, чтобы всегда быть кратным четырем.

Это означает, что размер представления base-64 строки размера n:

ceil(n / 3) * 4

Таким образом, для массива 16 КБ представление base-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.33333 для большого n.

Таким образом, 16 КБ * 4/3 дает очень немного больше 21,3 'КБ, или 21848 байт, если быть точным.

Надеюсь это поможет

Двоичный Беспорядок
источник
11

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

Крис Хилд
источник
5

Поскольку вопрос касался наихудшего возможного увеличения, я должен добавить, что обычно каждые 80 символов существуют разрывы строк. Это означает, что если вы сохраняете данные в кодировке base64 в текстовый файл в Windows, он добавит 2 байта, в Linux - 1 байт для каждой строки.

Увеличение от фактического кодирования было описано выше.

Жолт Скай
источник
3
Разве это не экстремальный случай, когда 1 исходный байт становится 4 base64 байта, то есть увеличение в 4 раза? Любой более длинный исходный материал получает лучшее соотношение, пока, как уже говорили другие, он асимптотически не приближается к 1.333 ...
Оли
1

Это будущая ссылка для меня. Поскольку вопрос наихудший , мы должны учитывать разрывы строк. В то время как RFC 1421 определяет максимальную длину строки в 64 символа, в RFC 2045 (MIME) говорится, что в одной строке должно быть не более 76 символов.

Последнее - то, что реализовала библиотека C #. Таким образом, в среде Windows, где разрыв строки составляет 2 символа (\ r \ n), мы получаем это:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

Примечание: Flooring - потому что во время моего теста с 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 ядре.

Лионет Чен
источник