2010-02-09 13 views
16

मैं उपयोगकर्ता पंजीकरण के लिए अपना खुद का कैप्चा सिस्टम लिख रहा हूं। तो मुझे जेनरेट कैप्चा चित्र प्राप्त करने के लिए एक उपयुक्त यूआरएल बनाने की जरूरत है। पीढ़ी इस तरह दिखता है:डीजेन्गो urlsafe बेस 64 डीकोडिंग डिक्रिप्शन

_cipher = cipher.new(settings.CAPTCHA_SECRET_KEY, cipher.MODE_ECB) 
_encrypt_block = lambda block: _cipher.encrypt(block + ' ' * (_cipher.block_size - len(block) % _cipher.block_size)) 
#... 
a = (self.rightnum, self.animal_type[1]) 
serialized = pickle.dumps(a) 
encrypted = _encrypt_block(serialized) 
safe_url = urlsafe_b64encode(encrypted) 

लेकिन तब मैं दृश्य समारोह में GET अनुरोध के माध्यम इस कुंजी प्राप्त करने के लिए कोशिश कर रहा हूँ, यह urlsafe_b64decode() के साथ पर विफल रहता है "चरित्र मानचित्रण लौटना चाहिए पूर्णांक, कोई नहीं या यूनिकोड" त्रुटि:

def captcha(request): 
    try: 
    key = request.REQUEST['key'] 
    decoded = urlsafe_b64decode(key) 
    decrypted = _decrypt_block(decoded) 
    deserialized = pickle.loads(decrypted) 
    return HttpResponse(deserialized) 
    except KeyError: 
    return HttpResponseBadRequest() 

मुझे लगता है कि पाया urlsafe_b64encode के उत्पादन पर एक str वहाँ है, लेकिन GET अनुरोध एक यूनिकोड ऑब्जेक्ट (फिर भी यह एक सही स्ट्रिंग है)। स्ट्र() ने मदद नहीं की है (यह django के अंदर गहरी त्रुटि डीकोड देता है), और यदि मैं कुंजी का उपयोग करता हूं। repr यह काम करता है, लेकिन डिक्रिप्टर त्रुटि के साथ काम नहीं करता है "इनपुट तार 16 लंबाई में से एक होना चाहिए"। एक परीक्षण फ़ाइल के अंदर यह सब निर्माण पूरी तरह से काम करता है, मैं समझ नहीं पा रहा हूं, क्या गलत है?

+0

क्या एन्क्रिप्शन आवश्यक है? कैप्चा की पीढ़ी सत्र डेटा सर्वर-साइड में सही जवाब नहीं दे सका? या आप इससे बचने की कोशिश कर रहे हैं? – MattH

+0

अभी तक इसके बारे में अभी तक नहीं सोचा था। लेकिन यह समस्या दिलचस्प है और मैं समझना चाहता हूं कि यह क्यों खुश होता है। – Enchantner

+0

'key = str (request.REQUEST ['key']) 'काम नहीं करता है? – MattH

उत्तर

32

समस्या यह है कि बी 64 डीकोड काफी स्पष्ट रूप से बाइट्स (एक स्ट्रिंग) ले सकता है, न कि यूनिकोड।

>>> import base64 
>>> test = "Hi, I'm a string" 
>>> enc = base64.urlsafe_b64encode(test) 
>>> enc 
'SGksIEknbSBhIHN0cmluZw==' 
>>> uenc = unicode(enc) 
>>> base64.urlsafe_b64decode(enc) 
"Hi, I'm a string" 
>>> base64.urlsafe_b64decode(uenc) 
Traceback (most recent call last): 
... 
TypeError: character mapping must return integer, None or unicode 

के बाद से आप जानते हैं कि आपके डेटा में केवल ASCII डेटा (कि क्या base64encode वापस आ जाएगी है), यह ASCII या UTF-8 बाइट्स के रूप में अपने यूनिकोड कोड अंक एन्कोड करने के लिए सुरक्षित होना चाहिए, उन बाइट्स के बराबर होगी शामिल ASCII आप की उम्मीद है।

>>> base64.urlsafe_b64decode(uenc.encode("ascii")) 
"Hi, I'm a string" 
+2

यह एक पाइथन वेबसर्वर में संबंधित समस्या के लिए मदद करता है। – hughdbrown

+1

"आप जानते हैं कि आपके डेटा में केवल ASCII डेटा है" - और यही कारण है कि मैं '.encode (" ascii ") लिखूंगा। –

+0

हां, "ascii" बेहतर होगा। अपडेट किया गया। –

3

मैंने समस्या हल की!

deserialized = pickle.loads(captcha_decrypt(urlsafe_b64decode(key.encode('ascii')))) 
return HttpResponse(str(deserialized)) 

लेकिन फिर भी मुझे समझ में नहीं आता, यह पहली बार क्यों काम नहीं करता था।

संबंधित मुद्दे