这是我的问题......
数据库以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的方法
修改 我已经改写了这个问题,因为我似乎没有在第一时间正确地认识到这个问题。
答案 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中的字节(bytes
,str
)上运行,而不是字符串(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])