我有以下功能来创建密文然后保存:
def create_credential(self):
des = DES.new(CIPHER_N, DES.MODE_ECB)
text = str(uuid.uuid4()).replace('-','')[:16]
cipher_text = des.encrypt(text)
return cipher_text
def decrypt_credential(self, text):
des = DES.new(CIPHER_N, DES.MODE_ECB)
return des.decrypt(text)
def update_access_credentials(self):
self.access_key = self.create_credential()
print repr(self.access_key) # "\xf9\xad\xfbO\xc1lJ'\xb3\xda\x7f\x84\x10\xbbv&"
self.access_password = self.create_credential()
self.save()
我会打电话给:
>>> from main.models import *
>>> u=User.objects.all()[0]
>>> u.update_access_credentials()
这是我得到的堆栈跟踪:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/deemarklit/Desktop/Example/Django/Example/main/models.py", line 747, in update_access_credentials
self.save()
File "/Users/deemarklit/Desktop/Example/Django/Example/main/models.py", line 731, in save
super(User, self).save(*args, **kwargs)
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 546, in save
force_update=force_update, update_fields=update_fields)
File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 626, in save_base
rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/Library/Python/2.7/site-packages/django/db/models/query.py", line 603, in _update
return query.get_compiler(self.db).execute_sql(None)
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py", line 1014, in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/Library/Python/2.7/site-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "/Library/Python/2.7/site-packages/django/db/backends/util.py", line 45, in execute
sql = self.db.ops.last_executed_query(self.cursor, sql, params)
File "/Library/Python/2.7/site-packages/django/db/backends/mysql/base.py", line 243, in last_executed_query
return cursor._last_executed.decode('utf-8')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf5 in position 738: invalid start byte
为什么会发生这种情况?我将如何解决这个问题?
答案 0 :(得分:1)
之所以发生这种情况,是因为您尝试在文本字段中保存非文本数据。改为使用非文本字段,或者通过例如文本将数据编码为文本。 Base-64编码。
答案 1 :(得分:1)
您正在将字节字符串存储到Unicode数据库字段中,因此它将尝试解码为Unicode。
使用可以存储不透明二进制数据的数据库字段,显式解码为Unicode(latin-1将字节一对一地映射到Unicode代码点)或将数据包装成可以存储为文本的表示。
对于Django 1.6及更高版本,请使用BinaryField
。对于早期版本,使用二进制到文本转换(例如Base64)优于解码到Latin-1;后者的结果不会给你有意义的文本数据,但Django可能会尝试显示它(例如在管理界面中)。
答案 2 :(得分:0)
在此处使用base64
编码和解码修复了此问题:
import base64
def create_credential(self):
des = DES.new(CIPHER_N, DES.MODE_ECB)
text = str(uuid.uuid4()).replace('-','')[:16]
cipher_text = des.encrypt(text)
base64_encrypted_message = base64.b64encode(cipher_text)
return base64_encrypted_message
def decrypt_credential(self, text):
text = base64.b64decode(text)
des = DES.new(CIPHER_N, DES.MODE_ECB)
message = des.decrypt(text)
return message