Короткий ответ
Вам нужно вставить bytes-like
объект ( bytes
, bytearray
и т. Д.) В base64.b64encode()
метод. Вот два способа:
>>> data = base64.b64encode(b'data to be encoded')
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Или с переменной:
>>> string = 'data to be encoded'
>>> data = base64.b64encode(string.encode())
>>> print(data)
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Зачем?
В Python 3 str
объекты не являются символьными массивами в стиле C (поэтому они не являются байтовыми массивами), а скорее являются структурами данных, которые не имеют встроенной кодировки. Вы можете закодировать эту строку (или интерпретировать ее) различными способами. Наиболее распространенным (и по умолчанию в Python 3) является utf-8, тем более что он обратно совместим с ASCII (хотя, как и наиболее широко используемые кодировки). Вот что происходит, когда вы берете a string
и вызываете .encode()
метод для него: Python интерпретирует строку в utf-8 (кодировка по умолчанию) и предоставляет вам массив байтов, которому она соответствует.
Кодировка Base-64 в Python 3
Первоначально заголовок вопроса задавался о кодировке Base-64. Продолжайте читать для Base-64 вещи.
base64
кодирование берет 6-битные двоичные фрагменты и кодирует их, используя символы AZ, az, 0-9, '+', '/' и '=' (некоторые кодировки используют разные символы вместо '+' и '/') , Это кодировка символов, основанная на математической конструкции системы счисления radix-64 или base-64, но они очень разные. Base-64 в математике - это система счисления, такая как двоичная или десятичная, и вы делаете это изменение основ на всем числе, или (если основание, из которого вы производите преобразование, является степенью 2 меньше 64) в кусках справа налево осталось.
В base64
кодировке перевод выполняется слева направо; эти первые 64 символа - вот почему это называется base64
кодированием . 65-й символ «=» используется для заполнения, поскольку кодирование извлекает 6-битные порции, но данные, которые обычно предназначены для кодирования, представляют собой 8-битные байты, поэтому иногда в последнем порции есть только два или 4 бита.
Пример:
>>> data = b'test'
>>> for byte in data:
... print(format(byte, '08b'), end=" ")
...
01110100 01100101 01110011 01110100
>>>
Если вы интерпретируете эти двоичные данные как одно целое число, то вы должны преобразовать их в base-10 и base-64 ( таблица для base-64 ):
base-2: 01 110100 011001 010111 001101 110100 (base-64 grouping shown)
base-10: 1952805748
base-64: B 0 Z X N 0
base64
кодирование , однако, перегруппирует эти данные таким образом:
base-2: 011101 000110 010101 110011 011101 00(0000) <- pad w/zeros to make a clean 6-bit chunk
base-10: 29 6 21 51 29 0
base-64: d G V z d A
Итак, «B0ZXN0» - это версия нашего бинарного кода с точки зрения математики, основанная на 64. Однако base64
кодирование должно выполнять кодирование в противоположном направлении (поэтому необработанные данные преобразуются в «dGVzdA»), а также имеет правило, чтобы сообщать другим приложениям, сколько места осталось в конце. Это делается путем заполнения конца символами '='. Таким образом, base64
кодировка этих данных - «dGVzdA ==», с двумя символами «=» для обозначения двух пар битов необходимо будет удалить с конца, когда эти данные будут декодированы, чтобы они соответствовали исходным данным.
Давайте проверим это, чтобы убедиться, что я нечестен:
>>> encoded = base64.b64encode(data)
>>> print(encoded)
b'dGVzdA=='
Зачем использовать base64
кодировку?
Допустим, мне нужно отправить данные кому-нибудь по электронной почте, например:
>>> data = b'\x04\x6d\x73\x67\x08\x08\x08\x20\x20\x20'
>>> print(data.decode())
>>> print(data)
b'\x04msg\x08\x08\x08 '
>>>
Я поставил две проблемы:
- Если я попытаюсь отправить это электронное письмо в Unix, оно будет отправлено, как только
\x04
будет прочитан символ, потому что это ASCII для END-OF-TRANSMISSION
(Ctrl-D), поэтому оставшиеся данные будут исключены из передачи.
- Кроме того, хотя Python достаточно умен, чтобы избежать всех моих злых управляющих символов, когда я печатаю данные напрямую, когда эта строка декодируется как ASCII, вы можете видеть, что «msg» не существует. Это потому, что я использовал три
BACKSPACE
символа и три SPACE
символа, чтобы стереть «MSG». Таким образом, даже если бы у меня не было EOF
персонажа, конечный пользователь не смог бы перевести текст с экрана на реальные необработанные данные.
Это просто демонстрация, чтобы показать вам, как трудно просто отправлять необработанные данные. Кодирование данных в формате base64 дает вам точно такие же данные, но в формате, который обеспечивает их безопасную отправку через электронные носители, такие как электронная почта.