base64.encodestring在python 3中失败

时间:2015-06-30 17:49:03

标签: python python-2.7 encoding base64 python-3.4

以下代码在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

我尝试搜索使用编码字符串的示例,但无法找到好的文档。我错过了一些明显的东西吗我在RHEL 2.6.18-371.11.1.el5

上运行它

3 个答案:

答案 0 :(得分:19)

在将字符串传递给encode()之前,您可以base64.encodestring将字符串(将其转换为字节字符串)。示例 -

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

答案 1 :(得分:7)

为了扩展Anand的答案(这是非常正确的),Python 2没有区分&#34;这里是一个我想要像文本一样对待的字符串&#34;和&#34;这里是一个字符串,我想把它当作一系列8位字节值&#34;。 Python 3牢牢地区分了两者,并且不会让你混淆它们:前者是str类型,后者是bytes类型。

当Base64对字符串进行编码时,您实际上并未将字符串视为文本,而是将其视为一系列8位字节值。这就是您在Python 3中从base64.encodestring()收到错误的原因:因为这是一个将字符串的字符作为 8位字节处理的操作,所以你应该传递一个bytes类型的参数,而不是str类型的参数。

因此,要将str对象转换为bytes对象,必须调用其encode()方法将其转换为一组8位字节值,无论使用哪种Unicode您选择使用的编码。 (除非您有 非常具体的 选择其他内容的理由,否则应该是UTF-8。)

答案 2 :(得分:2)

在Python 3中,encodestring docs说:

  

def encodestring(s):       &#34;&#34;&#34; encodebytes()的遗留别名。&#34;&#34;&#34;       进口警告       warnings.warn(&#34; encodestring()是一个不推荐使用的别名,使用encodebytes()&#34;,DeprecationWarning,2)       return 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/