#python #python-2.7 #base64
#python #python-2.7 #base64
Вопрос:
По какой-то причине я не могу вывести следующий фрагмент с ошибкой, хотя должен.
Вызывая функцию декодирования python2 base64 decodestring
с непечатаемыми символами, я ожидаю, что будет вызвано исключение, однако:
In [1]: import base64
In [2]: base64.decodestring("x01x01x01")
Out[2]: ''
Для сравнения, использование метода класса string дает тот же результат:
In [7]: "x01x01x01".decode("base64")
Out[7]: ''
Однако выполнение эквивалента для hex действительно обеспечит ожидаемое поведение (обратите внимание, что был добавлен дополнительный символ для выравнивания до кратных двум, как и ожидалось шестнадцатеричным декодером):
In [9]: "x01x01x01x01".decode("hex")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-1e73b7069a1d> in <module>()
----> 1 "x01x01x01x01".decode("hex")
/usr/lib/python2.7/encodings/hex_codec.pyc in hex_decode(input, errors)
40 """
41 assert errors == 'strict'
---> 42 output = binascii.a2b_hex(input)
43 return (output, len(input))
44
TypeError: Non-hexadecimal digit found
Несколько других попыток доказали, что обнаруженное поведение заключается в том, что декодер base64, в частности, игнорирует любые недопустимые символы вместо того, чтобы выдавать ошибку. Такое поведение наблюдается, хотя документально подтверждено, что декодер поддерживает только режим строгой обработки ошибок по умолчанию:
In [11]: "x01x01x01".decode("base64", errors="ignore")
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
<ipython-input-11-e0b65726a302> in <module>()
----> 1 "x01x01x01".decode("base64", errors="ignore")
/usr/lib/python2.7/encodings/base64_codec.pyc in base64_decode(input, errors)
39
40 """
---> 41 assert errors == 'strict'
42 output = base64.decodestring(input)
43 return (output, len(input))
AssertionError:
Такое поведение также наблюдается независимо от метода, используемого для выполнения встроенного кодека base64, который поставляется в комплекте с python2.7.
Кроме того, любой допустимый символ будет обработан должным образом, что приведет к странным результатам, таким как следующее:
In [6]: base64.decodestring("x01x01x01x01x01AA==")
Out[6]: 'x00'
In [7]: base64.decodestring("x01Ax01Ax01=x01=x01A")
Out[7]: 'x00'
In [8]: base64.decodestring("x01Notx01Ax01Base64x01Stringx01")
Out[8]: '6x8b@x05xabx1exebx84xadxae)xe0'
Мой вопрос двоякий:
- Прав ли я в своем анализе такого поведения?
- Почему это поведение было реализовано вместо того, чтобы соответствовать другим кодекам и
errors="strict"
API?
Ответ №1:
base64 был изобретен, чтобы разрешить инкапсуляцию двоичных файлов в текстовые протоколы. Эти протоколы могли иметь другие ограничения, такие как максимальный размер строки, что требовало вставки конца строк в строки, закодированные в base64. Чтобы быть максимально терпимым к вводимым данным, многие декодеры решили просто игнорировать любой непечатаемый символ.
Именно так был разработан модуль Python base64.
Комментарии:
1. Интересно. Спасибо! Не имело бы смысла поддерживать base64 errors =»ignore» вместо этого?