Python Unicode Ascii,序号不在范围内,令人沮丧

2024-05-16 07:10:31 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的问题。。。

数据库以unicode存储所有内容。 hashlib.sha256().digest()接受str并返回str

当我试图用数据填充散列函数时,会出现一个著名的错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 1: ordinal not in range(128)

这是我的数据

>>> db_digest
u"'\x90\x017~1\xe0\xaf4\xf2\xec\xd5]:j\xef\xe6\x80\x88\x89\xfe\xf7\x99,c\xff\xb7\x06hXR\x99\xad\x91\x93lM:\xafT\xc9j\xec\xc3\xb7\xea[\x80\xe0e\xd6\\\xd8\x16'\xcb6\xc8\xaa\xdf\xc9 :\xff"
>>> 
>>> hashlib.sha256(db_digest)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\x90' in position 1: ordinal not in range(128)
>>> 
>>> asc_db_digest
"'\x90\x017~1\xe0\xaf4\xf2\xec\xd5]:j\xef\xe6\x80\x88\x89\xfe\xf7\x99,c\xff\xb7\x06hXR\x99\xad\x91\x93lM:\xafT\xc9j\xec\xc3\xb7\xea[\x80\xe0e\xd6\\\xd8\x16'\xcb6\xc8\xaa\xdf\xc9 :\xff"
>>> hashlib.sha256(asc_db_digest)
<sha256 HASH object @ 0x7f7da0f04300>

所以我要的就是把数据库摘要转换成asc数据库摘要

编辑 我重新表述了这个问题,因为我一开始似乎没有正确地认识到这个问题。


Tags: 数据in数据库dbhashlibdigestsha256xff
3条回答

哈希操作的是字节(Python 2.x中的bytesstr),而不是字符串(2.x中的unicode,3.x中的str)。因此,无论如何必须提供字节。尝试:

hashlib.sha1(salt.encode('utf-8') + data).digest()

如果unicode字符串只包含0到255(字节)的代码点,则可以使用raw-unicode-escape编码将其转换为Python str:

>>> db_digest = u"'\x90\x017~1\xe0\xaf4\xf2\xec\xd5]:j\xef\xe6\x80\x88\x89\xfe\xf7\x99,c\xff\xb7\x06hXR\x99\xad\x91\x93lM:\xafT\xc9j\xec\xc3\xb7\xea[\x80\xe0e\xd6\\\xd8\x16'\xcb6\xc8\xaa\xdf\xc9 :\xff"
>>> hash_digest = "'\x90\x017~1\xe0\xaf4\xf2\xec\xd5]:j\xef\xe6\x80\x88\x89\xfe\xf7\x99,c\xff\xb7\x06hXR\x99\xad\x91\x93lM:\xafT\xc9j\xec\xc3\xb7\xea[\x80\xe0e\xd6\\\xd8\x16'\xcb6\xc8\xaa\xdf\xc9 :\xff"
>>> db_digest.encode('raw_unicode_escape')
"'\x90\x017~1\xe0\xaf4\xf2\xec\xd5]:j\xef\xe6\x80\x88\x89\xfe\xf7\x99,c\xff\xb7\x06hXR\x99\xad\x91\x93lM:\xafT\xc9j\xec\xc3\xb7\xea[\x80\xe0e\xd6\\\xd8\x16'\xcb6\xc8\xaa\xdf\xc9 :\xff"
>>> db_digest.encode('raw_unicode_escape') == hash_digest
True

哈希将包含0-255范围内的“字符”。这些都是有效的Unicode字符,但不是Unicode字符串。你需要改变它。最好的解决方案是将其编码成类似base64的内容。

也有一个简单的解决方案可以将直接返回的字节转换为伪Unicode字符串,就像您的数据库所做的那样:

hash_unicode = u''.join([unichr(ord(c)) for c in hash_digest])

您也可以走另一条路,但这更危险,因为“字符串”将包含ASCII范围0-127以外的字符,并且在尝试使用时可能会抛出错误。

asc_db_digest = ''.join([chr(ord(c)) for c in db_digest])

相关问题 更多 >