Python Unicode Ascii,Ordinal not in range,令人沮丧的错误

时间:2012-02-10 22:37:49

标签: python unicode

这是我的问题......

数据库以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>

所以我要求的是将db_digest转换为asc_db_digest的方法

修改 我已经改写了这个问题,因为我似乎没有在第一时间正确地认识到这个问题。

3 个答案:

答案 0 :(得分:5)

如果你有一个只包含0到255(字节)代码点的unicode字符串,你可以使用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

答案 1 :(得分:3)

哈希在Python 2.x中的字节(bytesstr)上运行,而不是字符串(2.x中的unicode,3.x中的str。因此,您必须提供字节。尝试:

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

答案 2 :(得分:1)

哈希将包含0-255范围内的“字符”。这些都是有效的Unicode字符,但它不是Unicode字符串。你需要以某种方式转换它。最好的解决方案是将其编码为base64

还有一个hacky解决方案将直接返回的字节转换为伪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])