base64.encodestring 失败 python 3
base64.encodestring failing in python 3
以下代码在 python 2 机器上成功运行:
base64_str = base64.encodestring('%s:%s' % (username,password)).replace('\n', '')
我正在尝试将其移植到 Python3,但是当我这样做时遇到以下错误:
>>> 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运行 这个
您可以 encode()
字符串(将其转换为字节字符串),然后再将其传递给 base64.encodestring
。例子-
base64_str = base64.encodestring(('%s:%s' % (username,password)).encode()).decode().strip()
为了扩展 Anand 的回答(非常正确),Python 2 在 "Here's a string which I want to treat like text" 和 "Here's a string which I want to treat like a sequence of 8-bit byte values" 之间几乎没有区别。 Python3牢牢区分两者,不让你混淆:前者是str
类型,后者是bytes
类型。
当您对字符串进行 Base64 编码时,您实际上并未将字符串视为文本,而是将其视为一系列 8 位字节值。这就是为什么您从 Python 3 中的 base64.encodestring()
收到错误的原因:因为这是一个将字符串字符作为 8 位字节 处理的操作,并且所以你应该传递一个 bytes
类型的参数而不是 str
.
类型的参数
因此,要将你的str
对象转换为bytes
对象,你必须调用它的encode()
方法将其转换为一组8位字节值,在您选择使用的任何 Unicode 编码。 (应该是 UTF-8,除非你有一个 非常具体的 选择其他东西的理由,但这是另一个话题)。
在 Python 3 encodestring 文档中说:
def encodestring(s):
"""Legacy alias of encodebytes()."""
import warnings
warnings.warn("encodestring() is a deprecated alias, use encodebytes()", 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/
以下代码在 python 2 机器上成功运行:
base64_str = base64.encodestring('%s:%s' % (username,password)).replace('\n', '')
我正在尝试将其移植到 Python3,但是当我这样做时遇到以下错误:
>>> 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运行 这个
您可以 encode()
字符串(将其转换为字节字符串),然后再将其传递给 base64.encodestring
。例子-
base64_str = base64.encodestring(('%s:%s' % (username,password)).encode()).decode().strip()
为了扩展 Anand 的回答(非常正确),Python 2 在 "Here's a string which I want to treat like text" 和 "Here's a string which I want to treat like a sequence of 8-bit byte values" 之间几乎没有区别。 Python3牢牢区分两者,不让你混淆:前者是str
类型,后者是bytes
类型。
当您对字符串进行 Base64 编码时,您实际上并未将字符串视为文本,而是将其视为一系列 8 位字节值。这就是为什么您从 Python 3 中的 base64.encodestring()
收到错误的原因:因为这是一个将字符串字符作为 8 位字节 处理的操作,并且所以你应该传递一个 bytes
类型的参数而不是 str
.
因此,要将你的str
对象转换为bytes
对象,你必须调用它的encode()
方法将其转换为一组8位字节值,在您选择使用的任何 Unicode 编码。 (应该是 UTF-8,除非你有一个 非常具体的 选择其他东西的理由,但这是另一个话题)。
在 Python 3 encodestring 文档中说:
def encodestring(s): """Legacy alias of encodebytes().""" import warnings warnings.warn("encodestring() is a deprecated alias, use encodebytes()", 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/