在App Engine上使用PyCrypto时遇到Python UnicodeEncodeError
我正在尝试将一个加密的查询字符串传递到另一个网址。
下面的代码让我遇到了这个错误:
Unicode编码错误:'ascii'编码无法在位置7编码字符u'\u04b7':序号不在范围内(128)
我使用的加密模块是 PyCrypto
我在App Engine上运行的是Python 2.5.2
页面A
import Crypto
from Crypto.Cipher import ARC4
obj=ARC4.new('stackoverflow')
msg = 'This is my secret msg'
encrypted = obj.encrypt(msg);
self.redirect('/pageb?' + urllib.urlencode({'q': encrypted}))
页面B
import Crypto
from Crypto.Cipher import ARC4
encrypted = self.request.get('q')
obj=ARC4.new('stackoverflow')
decrypted = obj.decrypt(encrypted)
get_data = cgi.parse_qs(decrypted)
self.response.out.write(decrypted)
self.response.out.write(pprint.pprint(get_data))
错误追踪信息
Traceback (most recent call last):
File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\_webapp25.py", line 701, in __call__
handler.get(*groups)
File "C:\Program Files\Google\google_appengine\demos\guestbook\guestbook.py", line 47, in get
decrypted = obj.decrypt(encrypted)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u04b7' in position 7: ordinal not in range(128)
2 个回答
1
从现有的信息来看,可以推测出某个地方需要一个字节串(bytestring),但是你给它提供了一个包含Unicode字符U+04B7(西里尔字母小写字母CHE带下行)的unicode
对象……这显然无法用ASCII编码(默认编码)表示,所以才会出现错误信息。
目前最好的建议是:别这么做。
更新 1:你还是没有问问题。不过:
这里的“某个地方”指的是某个加密工具的decrypt
方法。这个方法肯定需要一个str
对象。你可以用print repr(encrypted)
来查看一下。如果它看起来像是随机的垃圾数据(加密的数据应该是这样的),那么它在某个地方被从str
对象转换成了unicode
对象。你需要回头查查是怎么发生的。如果encrypted
看起来像是有意义的文本,那说明你的加密过程出了问题。
第一步:先用一些已知的明文,进行加密,然后在GAE的环境外再解密一次。每一步都用print repr()
来检查,这样你对下一步的预期就会合理一些。
第二步:在GAE中重复第一步,检查每一段数据的类型和内容。
更新 2:看起来你在页面A中有一个urlencode
,但在页面B中没有对应的urldecode
;这是不是问题的一部分?
6
一般来说,在你的加密内容中加入base64编码和解码的步骤。
import base64
base64_encrypted_message = base64.b64encode(encrypted_message)
// send your message via POST as GET can be seen on system logs
encrypted_message = base64.b64decode(base64_encrypted_message)
// decrypt your message
至于另一个错误,建议你了解一下unicode和utf-8对非ascii字符的编码。在把内容传给加密或解密函数之前,你需要先进行这一步。