Ваш вывод о том, что отступы не нужны, верен. Всегда можно однозначно определить длину ввода по длине закодированной последовательности.
Однако заполнение полезно в ситуациях, когда строки в кодировке base64 объединяются таким образом, что длины отдельных последовательностей теряются, как это может случиться, например, в очень простом сетевом протоколе.
Если незаполненные строки объединены, восстановить исходные данные невозможно, поскольку информация о количестве нечетных байтов в конце каждой отдельной последовательности теряется. Однако, если используются дополненные последовательности, нет двусмысленности, и последовательность в целом может быть декодирована правильно.
Изменить: иллюстрация
Предположим, у нас есть программа, которая кодирует слова base64, объединяет их и отправляет по сети. Он кодирует «I», «AM» и «TJM», складывает результаты вместе без заполнения и передает их.
I
кодируется в SQ
( SQ==
с заполнением)
AM
кодируется в QU0
( QU0=
с заполнением)
TJM
кодируется в VEpN
( VEpN
с заполнением)
Значит переданные данные есть SQQU0VEpN
. Приемник base64-декодирует это I\x04\x14\xd1Q)
вместо предполагаемого IAMTJM
. Результат - нонсенс, потому что отправитель уничтожил информацию о том, где заканчивается каждое слово в закодированной последовательности. Если бы отправитель отправил SQ==QU0=VEpN
вместо этого, получатель мог бы декодировать это как три отдельные последовательности base64, которые были бы объединены, чтобы дать IAMTJM
.
Зачем нужна прокладка?
Почему бы просто не разработать протокол так, чтобы каждое слово было префиксом целочисленной длины? Тогда получатель сможет правильно декодировать поток и не потребуется заполнение.
Это отличная идея, если мы знаем длину кодируемых данных до того, как начнем их кодировать. Но что, если вместо слов мы кодируем фрагменты видео с прямой камеры? Мы можем не знать заранее длину каждого фрагмента.
Если бы протокол использовал заполнение, вообще не было бы необходимости передавать длину. Данные могут быть закодированы по мере их поступления от камеры, каждый фрагмент заканчивается заполнением, и получатель сможет правильно декодировать поток.
Очевидно, это очень надуманный пример, но, возможно, он иллюстрирует, почему отступы могут быть полезны в некоторых ситуациях.
Кстати, вот базовый конвертер для произвольного базового преобразования, который я создал для вас. Наслаждайтесь! https://convert.zamicol.com/
Что такое символы заполнения?
Символы заполнения помогают удовлетворить требования к длине и не имеют смысла.
Десятичный пример заполнения: Учитывая произвольное требование, чтобы все строки имели длину 8 символов, число 640 может удовлетворить это требование, используя предшествующие 0 в качестве символов заполнения, поскольку они не имеют значения, «00000640».
Двоичное кодирование
Парадигма байтов: байт - это де-факто стандартная единица измерения, и любая схема кодирования должна относиться к байтам.
Base256 как раз вписывается в эту парадигму. Один байт равен одному символу в base256.
Base16 , шестнадцатеричный или шестнадцатеричный, использует 4 бита для каждого символа. Один байт может представлять два символа base16.
Base64 не вписывается равномерно в парадигму байтов (как и base32), в отличие от base256 и base16. Все символы base64 могут быть представлены 6 битами, на 2 бита меньше полного байта.
Мы можем представить кодировку base64 по сравнению с байтовой парадигмой в виде дроби: 6 бит на символ по 8 бит на байт . Уменьшенная эта дробь составляет 3 байта на 4 символа.
Это соотношение, 3 байта на каждые 4 символа base64, является правилом, которому мы хотим следовать при кодировании base64. Кодирование Base64 может обещать только измерения с 3-байтовыми пакетами , в отличие от base16 и base256, где каждый байт может стоять сам по себе.
Так почему же рекомендуется использовать заполнение, даже если кодирование может работать нормально без символов заполнения?
Если длина потока неизвестна или может быть полезно знать, когда именно заканчивается поток данных, используйте заполнение. Символы заполнения явно сообщают, что эти лишние места должны быть пустыми, и исключают любую двусмысленность. Даже если длина неизвестна с заполнением, вы будете знать, где заканчивается ваш поток данных.
Например, некоторые стандарты, такие как JOSE , не позволяют использовать символы заполнения. В этом случае, если чего-то не хватает, криптографическая подпись не будет работать или будут отсутствовать другие символы, отличные от base64 (например, "."). Хотя предположений о длине не делается, заполнение не требуется, потому что, если что-то не так, оно просто не сработает.
И это именно то, что говорится в RFC base64 :
Заполнение позволяет нам декодировать кодировку base64 без потери битов. Без заполнения больше нет явного подтверждения измерения в трехбайтовых пакетах. Без заполнения вы не сможете гарантировать точное воспроизведение исходной кодировки без дополнительной информации, обычно из другого места в вашем стеке, например TCP, контрольных сумм или других методов.
Примеры
Вот пример формы RFC 4648 ( http://tools.ietf.org/html/rfc4648#section-8 )
Каждый символ внутри функции «BASE64» использует один байт (base256). Затем мы переводим это в base64.
Вот кодировщик, с которым вы можете поиграть: http://www.motobit.com/util/base64-decoder-encoder.asp
источник
char*
, вам нужен либо размер строки, либо нулевой терминатор. Заполнение избыточно. Следовательно, вопрос ОП.В наши дни от этого мало пользы. Итак, давайте посмотрим на это как на вопрос, какова могла быть первоначальная историческая цель.
Кодирование Base64 впервые появляется в RFC 1421 от 1993 года. Этот RFC фактически ориентирован на шифрование электронной почты, а base64 описан в одном небольшом разделе 4.3.2.4 .
Этот RFC не объясняет цель заполнения. Ближе всего к упоминанию первоначальной цели у нас есть это предложение:
Он не предполагает конкатенации (верхний ответ здесь) или простоты реализации в качестве явной цели для заполнения. Однако, рассматривая полное описание, есть основания предположить, что это могло быть предназначено для того, чтобы помочь декодеру считывать ввод в 32-битных единицах ( «квантах» ). Сегодня это бесполезно, однако в 1993 году небезопасный код C, скорее всего, действительно воспользовался бы этим свойством.
источник
b'Zm9vYmFyZm9vYg==' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy' b'Zm9vYmFyZm9vYmFyZg==' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v'
такая же, как уb'Zm9vYmFyZm9vYg=' b'Zm9vYmFyZm9vYmE=' b'Zm9vYmFyZm9vYmFy=' b'Zm9vYmFyZm9vYmFyZg=' b'Zm9vYmFyZm9vYmFyZm8=' b'Zm9vYmFyZm9vYmFyZm9v='