Можно ли удалить равные знаки из строки base64?

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

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

Спасибо.

Ответы

Ответ 1

Глядя на ваш код:

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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))

Ответ 4

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

Ответ 5

Кроме того, в случае, когда @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.