Рубрики
Без рубрики

base64 – кодировать двоичные данные с помощью ASCII

Автор оригинала: Doug Hellmann.

Цель:

Модуль base64 содержит функции для перевода двоичных файлов. данные в подмножество ASCII, подходящее для передачи с использованием протоколы с открытым текстом.

Кодировки base64, base32, base16 и base85 преобразуют 8-битные байты в значения, которые соответствуют диапазону печатаемых символов ASCII, обменивая больше битов для представления данных для совместимости с системами, которые поддерживают только данные ASCII, например SMTP. Значения base соответствуют длине алфавита, используемого в каждой кодировке. Существуют также безопасные для URL-адресов варианты исходных кодировок, в которых используются несколько иные алфавиты.

Кодировка Base 64

Это базовый пример кодирования некоторого текста.

base64_b64encode.py

import base64
import textwrap

# Load this source file and strip the header.
with open(__file__, 'r', encoding'utf-8') as input:
    raw  input.read()
    initial_data  raw.split('#end_pymotw_header')[1]

byte_string  initial_data.encode('utf-8')
encoded_data  base64.b64encode(byte_string)

num_initial  len(byte_string)

# There will never be more than 2 padding bytes.
padding  3 - (num_initial % 3)

print('{} bytes before encoding'.format(num_initial))
print('Expect {} padding bytes'.format(padding))
print('{} bytes after encoding\n'.format(len(encoded_data)))
print(encoded_data)

Входные данные должны быть байтовой строкой, поэтому строка Unicode сначала кодируется в UTF-8. Выходные данные показывают, что 185 байтов источника UTF-8 расширяются до 248 байтов после кодирования.

Примечание

В кодированных данных, созданных библиотекой, нет возврата каретки, но вывод был искусственно обернут, чтобы он лучше умещался на странице.

$ python3 base64_b64encode.py

184 bytes before encoding
Expect 2 padding bytes
248 bytes after encoding

b'CmltcG9ydCBiYXNlNjQKaW1wb3J0IHRleHR3cmFwCgojIExvYWQgdGhpcyBzb3
VyY2UgZmlsZSBhbmQgc3RyaXAgdGhlIGhlYWRlci4Kd2l0aCBvcGVuKF9fZmlsZV
9fLCAncicsIGVuY29kaW5nPSd1dGYtOCcpIGFzIGlucHV0OgogICAgcmF3ID0gaW
5wdXQucmVhZCgpCiAgICBpbml0aWFsX2RhdGEgPSByYXcuc3BsaXQoJw=='

Базовое 64 декодирование

b64decode () преобразует закодированную строку обратно в исходную форму, взяв четыре байта и преобразовав их в исходные три с помощью таблицы поиска.

base64_b64decode.py

import base64

encoded_data  b
decoded_data  base64.b64decode(encoded_data)
print('Encoded :', encoded_data)
print('Decoded :', decoded_data)

Процесс кодирования просматривает каждую последовательность из 24 битов на входе (три байта) и кодирует те же самые 24 бита, распределенные по четырем байтам на выходе. Знаки равенства в конце вывода – это вставка заполнения, поскольку в этом примере количество битов в исходной строке не делится на 24 без остатка.

$ python3 base64_b64decode.py

Encoded : b'VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWFyLg=='
Decoded : b'This is the data, in the clear.'

Значение, возвращаемое функцией b64decode () , является байтовой строкой. Если известно, что содержимое является текстом, байтовая строка может быть преобразована в объект Unicode. Однако смысл использования кодировки base 64 заключается в том, чтобы иметь возможность передавать двоичные данные, поэтому не всегда безопасно предполагать, что декодируемое значение является текстом.

URL-безопасные варианты

Поскольку в алфавите base64 по умолчанию могут использоваться + и /, а эти два символа используются в URL-адресах, часто необходимо использовать альтернативный

base64_urlsafe.py

import base64

encodes_with_pluses  b'\xfb\xef'
encodes_with_slashes  b'\xff\xff'

for original in [encodes_with_pluses, encodes_with_slashes]:
    print('Original         :', repr(original))
    print('Standard encoding:',
          base64.standard_b64encode(original))
    print('URL-safe encoding:',
          base64.urlsafe_b64encode(original))
    print()

+ заменяется на - , а / заменяется на подчеркивание ( _ ). В остальном алфавит тот же.

$ python3 base64_urlsafe.py

Original         : b'\xfb\xef'
Standard encoding: b'++8='
URL-safe encoding: b'--8='

Original         : b'\xff\xff'
Standard encoding: b'//8='
URL-safe encoding: b'__8='

Другие кодировки

Помимо Base64, модуль предоставляет функции для работы с данными в кодировке Base85, Base32 и Base16 (hex).

base64_base32.py

import base64

original_data  b'This is the data, in the clear.'
print('Original:', original_data)

encoded_data  base64.b32encode(original_data)
print('Encoded :', encoded_data)

decoded_data  base64.b32decode(encoded_data)
print('Decoded :', decoded_data)

Алфавит Base32 включает 26 заглавных букв из набора ASCII и цифры от 2 до 7.

$ python3 base64_base32.py

Original: b'This is the data, in the clear.'
Encoded : b'KRUGS4ZANFZSA5DIMUQGIYLUMEWCA2LOEB2GQZJAMNWGKYLSFY==
Decoded : b'This is the data, in the clear.'

Функции Base16 работают с шестнадцатеричным алфавитом.

base64_base16.py

import base64

original_data  b'This is the data, in the clear.'
print('Original:', original_data)

encoded_data  base64.b16encode(original_data)
print('Encoded :', encoded_data)

decoded_data  base64.b16decode(encoded_data)
print('Decoded :', decoded_data)

Каждый раз, когда количество бит кодирования уменьшается, вывод в закодированном формате занимает больше места.

$ python3 base64_base16.py

Original: b'This is the data, in the clear.'
Encoded : b'546869732069732074686520646174612C20696E207468652063
6C6561722E'
Decoded : b'This is the data, in the clear.'

Функции Base85 используют расширенный алфавит, который занимает больше места, чем основание 64.

base64_base85.py

import base64

original_data  b'This is the data, in the clear.'
print('Original    : {} bytes {!r}'.format(
    len(original_data), original_data))

b64_data  base64.b64encode(original_data)
print('b64 Encoded : {} bytes {!r}'.format(
    len(b64_data), b64_data))

b85_data  base64.b85encode(original_data)
print('b85 Encoded : {} bytes {!r}'.format(
    len(b85_data), b85_data))

a85_data  base64.a85encode(original_data)
print('a85 Encoded : {} bytes {!r}'.format(
    len(a85_data), a85_data))

Существует несколько кодировок Base85, и различные варианты используются в Mercurial, git и формате файлов PDF. Python включает две реализации: b85encode () реализует версию, используемую в Git и Mercurial, а a85encode () реализует вариант Ascii85, используемый файлами PDF.

$ python3 base64_base85.py

Original    : 31 bytes b'This is the data, in the clear.'
b64 Encoded : 44 bytes b'VGhpcyBpcyB0aGUgZGF0YSwgaW4gdGhlIGNsZWF
yLg=='
b85 Encoded : 39 bytes b'RA^~)AZc?TbZBKDWMOn+EFfuaAarPDAY*K0VR9}
'
a85 Encoded : 39 bytes b'<+oue+DGm>FD,5.A79Rg/0JYE+EV:.+Cf5!@<*t
'

Смотрите также