Можно ли удалить знаки равенства из строки base64? - PullRequest
18 голосов
/ 26 января 2012

У меня есть строка, которую я кодирую в base64 для экономии места.Разве это большое дело, если я уберу знак равенства в конце?Это значительно уменьшило бы энтропию?Что я могу сделать, чтобы убедиться, что длина результирующей строки фиксирована?

Ответы [ 6 ]

17 голосов
/ 26 января 2012

Каждые 3 байта, которые необходимо кодировать, поскольку Base64 преобразуются в 4 символа ASCII, а символ '=' используется для дополнения результата, чтобы всегда было кратно 4 закодированным символам.Если у вас есть точное кратное 3 байта, вы не получите знак равенства.Один запасной байт означает, что в конце вы получите два символа «=».Два свободных байта означают, что в конце вы получите один символ «=».в зависимости от того, как вы декодируете строку, он может видеть или не видеть это как допустимую строку.С примером строки, которую вы имеете, он не декодирует, но некоторые простые строки, которые я пытался сделать, декодируют.

Вы можете прочитать эту страницу для лучшего понимания строк base64 и кодирования / декодирования.

http://www.nczonline.net/blog/2009/12/08/computer-science-in-javascript-base64-encoding/

Существуют бесплатные онлайн-кодировщики / декодеры, которые вы можете использовать для проверки выходной строки

15 голосов
/ 26 января 2012

Просмотр вашего кода:

>>> base64.b64encode(combined.digest(), altchars="AB")
'PeFC3irNFx8fuzwjAzAfEAup9cz6xujsf2gAIH2GdUM='

Строка, которая кодируется в base64, является результатом функции с именем digest().Если ваша функция дайджеста выдает значения фиксированной длины (например, вычисляет дайджесты MD5 или SHA1), тогда параметр для b64encode всегда будет иметь одинаковую длину.тогда вы можете убрать конечные знаки равенства, потому что их всегда будет одинаковое количество.Если вы это сделаете, просто добавьте к строке одинаковое количество знаков равенства перед декодированием.

Если дайджест не имеет фиксированной длины, то обрезать знаки равенства небезопасно.

Редактировать: Похоже, вы могли использовать дайджест SHA-256?Дайджест SHA-256 составляет 256 бит (или 32 байта).32 байта - это 10 групп по 3, плюс две оставшиеся.Как вы увидите из раздела Википедии о заполнении ;это означало бы, что у вас всегда есть один трейлинг равный.Если это SHA-256, тогда можно будет удалить его, если вы не забудете добавить его еще раз перед декодированием.

10 голосов
/ 27 января 2012

Удалять знаки равенства хорошо, если вы знаете, что они делают.

Base64 выводит 4 символа на каждые 3 байта, которые он кодирует (другими словами, каждый символ кодирует 6 бит).Символы заполнения добавляются таким образом, что любая строка base64 всегда кратна длине 4, а символы заполнения фактически не кодируют никаких данных.(Я не могу сказать наверняка , почему это было сделано - как способ проверки ошибок, была ли строка обрезана, чтобы облегчить декодирование, или что-то еще?).

В любом случае это означает, что если у вас есть x base64 символов (без заполнения), будет 4-(x%4) символов заполнения.(Хотя x%4=1 никогда не произойдет из-за факторизации 6 и 8).Поскольку они не содержат фактических данных и могут быть восстановлены, я часто удаляю их, когда хочу сэкономить место, например: ::

from base64 import b64encode, b64decode

# encode data
raw = b'\x00\x01'
enc = b64encode(raw).rstrip("=")

# func to restore padding
def repad(data):
     return data + "=" * (-len(data)%4)
raw = b64decode(repad(enc))
1 голос
/ 12 февраля 2014

За исключением случая, на который указывает @Martin Ellis, путаница с символами заполнения может привести к получению

TypeError: Incorrect padding

и производя мусор, пока вы на нем.

Как утверждает @MattH, base64 будет делать противоположное сохранению пространства.

Вместо того, чтобы экономить пространство , вам следует применять алгоритмы сжатия, такие как zlib.

Например, zlib

import zlib

s = '''large string....'''
compressed = zlib.compress(s)

compression_ratio = len(s)*1.0/len(compressed)    

# And later...
out = zlib.decompress(compressed) 

# The above function is also good for relieving stress.
1 голос
/ 26 января 2012

это отступы, и вы не экономите много, удаляя их, так как их не больше двух, поэтому, если вы хотите сэкономить место, посмотрите где. и что касается энтропии, вы сжимаете эти строки base64? Если это так, даже если вы удалите их, они не окажут большого влияния на сжатый размер.

0 голосов
/ 26 января 2012

Я так не думаю.http://en.wikipedia.org/wiki/Base64#Padding

эти "полезны"

...