У меня есть данные в кодировке base64, которые я хочу преобразовать обратно в двоичные, даже если в них есть ошибка заполнения. Если я использую
base64.decodestring(b64_string)
это вызывает ошибку "Неправильное заполнение". Есть другой способ?
ОБНОВЛЕНИЕ: Спасибо за отзывы. Честно говоря, все упомянутые методы казались несколько неудачными, поэтому я решил попробовать openssl. Следующая команда сработала:
openssl enc -d -base64 -in b64string -out binary_data
base64.b64decode(strg, '-_')
? Это априори, без предоставления каких-либо примеров данных, наиболее вероятное решение вашей проблемы с помощью Python. Предлагаемые "методы" были предложениями ОТЛАДКИ, ОБЯЗАТЕЛЬНО "удачно", учитывая скудность предоставленной информации.base64.urlsafe_b64decode(s)
sorted(list(set(b64_string)))
пожалуйста? Не раскрывая ничего конфиденциального для компании, это должно показать, какие символы использовались для кодирования исходных данных, что, в свою очередь, может предоставить достаточно информации, чтобы обеспечить решение без промахов.Ответы:
Как сказано в других ответах, данные base64 могут быть повреждены различными способами.
Однако, как говорит Википедия , удаление отступа (символы '=' в конце данных в кодировке base64) "без потерь":
Так что, если это единственное, что "не так" с вашими данными base64, можно просто добавить отступы. Я придумал это, чтобы иметь возможность анализировать URL-адреса "данных" в WeasyPrint, некоторые из которых были base64 без заполнения:
Тесты для этой функции: weasyprint / tests / test_css.py # L68
источник
str(data)
base64.decodestring
устарелbase64.decodebytes
в Py3, но для совместимости версий лучше использоватьbase64.b64decode
.base64
модуль игнорирует недопустимые символы, отличные от base64, во входных данных, вам сначала необходимо нормализовать данные. Удалите все, кроме буквы, цифры/
или+
, а затем добавьте отступ.Просто добавьте отступ по мере необходимости. Однако прислушайтесь к предупреждению Майкла.
источник
===
всегда работает. Любые лишние=
символы, по-видимому, безопасно отбрасываются Python.Кажется, вам просто нужно добавить отступ к байтам перед декодированием. На этот вопрос есть много других ответов, но я хочу указать, что (по крайней мере, в Python 3.x)
base64.b64decode
любые дополнительные отступы будут обрезаны, если их достаточно.Итак, что-то вроде:
b'abc='
работает так же хорошо, какb'abc=='
(какb'abc====='
).Это означает, что вы можете просто добавить максимальное количество символов заполнения, которое вам когда-либо понадобится, а это три (
b'==='
), и base64 обрежет все ненужные.Это позволяет вам писать:
что проще, чем:
источник
binascii.Error: Invalid base64-encoded string: number of data characters (5) cannot be 1 more than a multiple of 4
. Спасибо за указание на это!«Неправильное заполнение» может означать не только «недостающее заполнение», но также (хотите верьте, хотите нет) «неправильное заполнение».
Если предложенные методы "добавления заполнения" не работают, попробуйте удалить некоторые завершающие байты:
Обновление: любые попытки добавить отступы или удалить, возможно, плохие байты с конца, должны выполняться ПОСЛЕ удаления любых пробелов, в противном случае расчеты длины будут нарушены.
Было бы неплохо, если бы вы показали нам (короткий) образец данных, которые вам необходимо восстановить. Отредактируйте свой вопрос и скопируйте / вставьте результат
print repr(sample)
.Обновление 2: возможно, что кодирование было выполнено безопасным для URL-адресов способом. В этом случае вы сможете увидеть в своих данных символы минуса и подчеркивания, и вы сможете декодировать их с помощью
base64.b64decode(strg, '-_')
Если вы не видите в данных символы минуса и подчеркивания, но видите знаки плюса и косой черты, значит, у вас другая проблема, и вам могут понадобиться уловки add-padding или remove-cruft.
Если вы не видите в данных ни минуса, ни подчеркивания, ни плюса, ни косой черты, вам нужно определить два альтернативных символа; это будут те, кого нет в [A-Za-z0-9]. Затем вам нужно будет поэкспериментировать, чтобы увидеть, в каком порядке они должны использоваться во втором аргументе
base64.b64decode()
Обновление 3 : Если ваши данные «конфиденциальны»:
(а) вы должны сообщить об этом заранее
(б) мы можем изучить другие способы понимания проблемы, которая, скорее всего, будет связана с тем, какие символы используются вместо
+
и/
в кодирующий алфавит или другие символы форматирования или посторонние символы.Одним из таких способов было бы изучить, какие нестандартные символы присутствуют в ваших данных, например
источник
Использовать
Кредит идет на комментарий где-то здесь.
источник
Если есть ошибка заполнения, это, вероятно, означает, что ваша строка повреждена; Строки в кодировке base64 должны иметь длину, кратную четырем. Вы можете попробовать добавить символ заполнения (
=
) самостоятельно, чтобы сделать строку кратной четырем, но он уже должен иметь это, если что-то не так.источник
Проверьте документацию к источнику данных, который вы пытаетесь декодировать. Возможно ли, что вы хотели использовать
base64.urlsafe_b64decode(s)
вместоbase64.b64decode(s)
? Это одна из причин, по которой вы могли видеть это сообщение об ошибке.Это, например, относится к различным API Google, таким как Google Identity Toolkit и полезные нагрузки Gmail.
источник
urlsafe_b64decode
также требует заполнения.base64.urlsafe_b64decode
.Добавление отступов довольно ... неудобно. Вот функция, которую я написал с помощью комментариев в этой ветке, а также вики-страницу для base64 (она на удивление полезна) https://en.wikipedia.org/wiki/Base64#Padding .
источник
Вы можете просто использовать,
base64.urlsafe_b64decode(data)
если пытаетесь декодировать веб-изображение. Он автоматически позаботится о заполнении.источник
Есть два способа исправить входные данные, описанные здесь, или, более конкретно и в соответствии с OP, сделать так, чтобы метод b64decode модуля Python base64 мог обрабатывать входные данные во что-то, не вызывая неперехваченного исключения:
Если это вызывает исключение, тогда
я. Поймать через try / except,
II. (R?) Удалите любые символы = из входных данных (NB, это может быть необязательно),
iii. Добавьте A == к входным данным (A == - P == будет работать),
iv. Вызов base64.b64decode (...) с этими A == - добавленными входными данными
Результат из пункта 1 или пункта 2 выше даст желаемый результат.
Предостережения
Это не гарантирует, что декодированный результат будет тем, что было изначально закодировано, но он (иногда?) Даст OP достаточно для работы:
См. Что мы знаем и предположения ниже.
TL; DR
Из некоторых быстрых тестов base64.b64decode (...)
похоже, что он игнорирует символы, отличные от [A-Za-z0-9 + /]; который включает игнорирование = s, если они не являются последними символами в проанализированной группе из четырех, и в этом случае = s завершает декодирование (a = b = c = d = дает тот же результат, что и abc =, и a = = b == c == дает тот же результат, что и ab ==).
Также кажется, что все добавленные символы игнорируются после точки, в которой base64.b64decode (...) завершает декодирование, например, с знака = как четвертого в группе.
Как отмечалось в нескольких комментариях выше, в конце входных данных требуется либо ноль, либо один, либо два = s заполнения, когда значение [количество проанализированных символов до этой точки по модулю 4] равно 0 или 3, или 2 соответственно. Итак, из пунктов 3. и 4. выше, добавление двух или более = s к входным данным исправит любые проблемы с [неправильным заполнением] в этих случаях.
ОДНАКО, декодирование не может обработать случай, когда [общее количество проанализированных символов по модулю 4] равно 1, потому что требуется как минимум два закодированных символа для представления первого декодированного байта в группе из трех декодированных байтов. В ООН повреждена кодированные входные данные, это [N по модулю 4] = 1 случай никогда не бывает, но как ОП говорится , что символы могут отсутствовать, это может произойти здесь. Вот почему простое добавление = s не всегда будет работать, и почему добавление A == будет работать, а добавление == - нет. NB. Использование [A] почти произвольно: оно добавляет к декодируемым только очищенные (нулевые) биты, что может быть правильным или неправильным, но тогда объект здесь не правильность, а завершение с помощью base64.b64decode (...) без исключений .
Что мы знаем из OP и особенно последующих комментариев, так это
openssl enc ...
работает.Предположения
Github
Вот оболочка для реализации этого решения:
https://github.com/drbitboy/missing_b64
источник
Ошибка неправильного заполнения возникает из-за того, что иногда метаданные также присутствуют в закодированной строке. Если ваша строка выглядит примерно так: 'data: image / png; base64, ... base 64 stuff ....', тогда вам нужно удалить первый часть перед его расшифровкой.
Скажем, если у вас есть строка в кодировке base64, попробуйте нижеприведенный фрагмент ..
источник
Просто добавьте дополнительные символы, такие как «=» или любые другие, и сделайте их кратными 4, прежде чем пытаться декодировать значение целевой строки. Что-то вроде;
источник
В случае, если эта ошибка возникла с веб-сервера: попробуйте кодировать URL-адрес вашего сообщения. Я отправлял POST через "curl" и обнаружил, что не кодировал URL-адрес моего значения base64, поэтому символы вроде "+" не были экранированы, поэтому логика декодирования URL-адреса веб-сервера автоматически запускала url-decode и преобразовывала + в пробелы.
«+» - допустимый символ base64 и, возможно, единственный символ, который искажается из-за неожиданного декодирования URL.
источник
В моем случае я столкнулся с этой ошибкой при разборе электронного письма. Я получил вложение в виде строки base64 и извлек его через re.search. В конце концов, в конце оказалась странная дополнительная подстрока.
Когда я удалил
--_=ic0008m4wtZ4TqBFd+sXC8--
и разделил строку, синтаксический анализ был исправлен.Поэтому я советую убедиться, что вы декодируете правильную строку base64.
источник
Вы должны использовать
По умолчанию альт-символы
'+/'
.источник
Я тоже столкнулся с этой проблемой, и ничего не помогло. Наконец-то мне удалось найти решение, которое мне подходит. Я заархивировал содержимое в base64, и это случилось с 1 из миллиона записей ...
Это вариант решения, предложенного Саймоном Сапином.
В случае, если отступы отсутствуют 3, я удаляю последние 3 символа.
Вместо "0gA1RD5L / 9AUGtH9MzAwAAA =="
Получаем "0gA1RD5L / 9AUGtH9MzAwAA"
Согласно этому ответу Trailing As в base64 причина - нули. Но я до сих пор не понимаю, почему кодировщик все испортил ...
источник