我在字符串对象中将一些汉字转换为UTF-8,以进行某些操作。现在,当我尝试将字符串对象转换回字节对象时遇到问题。
我尝试使用bytes()
:
a = '一'
bytes_value = a.encode('utf-8')
string_value = str(b)
bytes_value_again = bytes(string_value)
我想将其转换回字节对象,因此可以使用decode('utf-8')
将其转换回原始汉字。
答案 0 :(得分:1)
请勿使用bytes
将str(bytes_value)
对象转换为字符串。您创建了printable representation of the object。
从bytes
到str
转换的正确方法是将字节解码到Unicode。如果您有UTF-8字节,请使用bytes.decode()
method用该编解码器进行解码:
string_value = bytes_value.decode('utf8')
如果您想使用str()
函数,还可以 指定编码,请参见str(bytes_value, encoding)
form in the documentation:
string_value = str(bytes_value, 'utf8')
如果您不小心使用了str(bytes_value)
,但现在无法通过修复该错误并重新运行代码来获取原始值,则可以使用ast.literal_eval()
来恢复原始值:
bytes_representation = str(bytes_value) # "b'....'"
recovered_bytes_value = ast.literal_eval(bytes_representation)
这只能用于恢复数据,而不能用作生产级序列化机制。 ast.literal_eval()
的运行速度很慢,并且在用户提供的输入上使用时,也无法免受拒绝服务攻击(可能会导致Python崩溃或由于输入错误而大大降低其速度)。
如果您使用的API应该真正对字节起作用,但由于某种原因仅接受字符串(通常是错误设计和实现的API的警告信号),则可以使用binary-to-ASCII encoding(包括{{ 3}})或将二进制数据解码为Latin-1。
如果您要对数据进行加密,则这一点甚至更为重要。 bytes()
对象的可打印表示形式仅使用ASCII字符,始终以b'
或b"
开头,并且始终以'
或"
结尾。用base64 / base16 / base32 / base85的有限范围表示任何不可打印的字节(所有256个可能的字节值中的一半以上)。所有这些使确定的攻击者更容易破解您的加密。最佳实践加密库将使您直接加密bytes
。实际上,通常首选来加密字节。