в base64.encodestring не в Python 3

следующий фрагмент кода успешно выполняется на компьютере python 2:

base64_str = base64.encodestring('%s:%s' % (username,password)).replace('n', '')

Я пытаюсь перенести его на Python 3, но когда я это делаю, я сталкиваюсь со следующей ошибкой:

>>> a = base64.encodestring('{0}:{1}'.format(username,password)).replace('n','')
Traceback (most recent call last):
  File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 519, in _input_type_check
    m = memoryview(s)
TypeError: memoryview: str object does not have the buffer interface

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 548, in encodestring
    return encodebytes(s)
  File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 536, in encodebytes
    _input_type_check(s)
  File "/auto/pysw/cel55/python/3.4.1/lib/python3.4/base64.py", line 522, in _input_type_check
    raise TypeError(msg) from err
TypeError: expected bytes-like object, not str

Я попытался найти примеры использования encodestring, но не смог найти хороший документ. Я упускаю что-то очевидное? Я запускаю это на RHEL 2.6.18-371.11.1.el5

3 ответов


вы можете encode() строка (чтобы преобразовать ее в байтовую строку), прежде чем передать ее в base64.encodestring . Пример -

base64_str = base64.encodestring(('%s:%s' % (username,password)).encode()).decode().replace('\n', '')

чтобы расширить ответ Ананда (что совершенно правильно), Python 2 сделал небольшое различие между "вот строка, которую я хочу рассматривать как текст" и "вот строка, которую я хочу рассматривать как последовательность 8-битных байтовых значений". Python 3 твердо различает два и не позволяет вам смешивать их: первый -str тип, и последний является bytes тип.

когда вы кодируете строку Base64, вы на самом деле не обрабатываете строку как текст, вы обрабатываете ее как ряд 8-битных байтовых значений. Вот почему вы получаете ошибку от base64.encodestring() в Python 3: потому что это операция, которая имеет дело с строки символов 8-битный байт, и поэтому вы должны передать ей параметр типа bytes вместо параметра типа str.

поэтому, чтобы преобразовать ваш str объект в bytes объект, вы должны вызвать его encode() метод, чтобы превратить его в набор 8-битных байтовых значений, в любой кодировке Unicode у вас есть выбран для использования. (Который должен быть UTF-8, Если у вас нет очень специфический причина выбрать что-то другое, но это другая тема).


в Python 3 encodestring docs говорится:

деф encodestring(с): """Устаревший псевдоним encodebytes ().""" импорт предупреждений предупреждение.warn ("encodestring () - устаревший псевдоним, используйте encodebytes ()", DeprecationWarning, 2) возврат encodebytes (s)

вот рабочий код для Python 3.5.1, он также показывает, как кодировать url:

def _encodeBase64(consumer_key, consumer_secret):
    """
     :type consumer_key: str
     :type consumer_secret: str
     :rtype str
    """
    # 1. URL encode the consumer key and the consumer secret according to RFC 1738.
    dummy_param_name = 'bla'
    key_url_encoded = urllib.parse.urlencode({dummy_param_name: consumer_key})[len(dummy_param_name) + 1:]
    secret_url_encoded = urllib.parse.urlencode({dummy_param_name: consumer_secret})[len(dummy_param_name) + 1:]

    # 2. Concatenate the encoded consumer key, a colon character “:”, and the encoded consumer secret into a single string.
    credentials = '{}:{}'.format(key_url_encoded, secret_url_encoded)

    # 3. Base64 encode the string from the previous step.
    bytes_base64_encoded_credentials = base64.encodebytes(credentials.encode('utf-8'))

    return bytes_base64_encoded_credentials.decode('utf-8').replace('\n', '')

(Я уверен, что это может быть более кратким, я новичок в Python...)

также смотри:http://pythoncentral.io/encoding-and-decoding-strings-in-python-3-x/