標籤:blog http io 檔案 資料 2014 ar 問題
事情是這樣的:
博主嘗試用Python的sqlite3資料庫存放加密後的使用者名稱密碼資訊,表是這樣的
CREATE TABLE IF NOT EXISTS user(userID INTEGER PRIMARY KEY AUTOINCREMENT,userStudentID BLOB NOT NULL UNIQUE ON CONFLICT IGNORE,userPassword BLOB NOT NULL);
其中userStudentID and UserPassword 儲存成了BLOB類型,作為二進位儲存。
但當博主把加密後的位元組串插入資料庫時,卻報出如下錯誤:
sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.
顯然它把博主的位元組串當成了未經編碼的字串。此時不能參考它的做法,把text_factory 置為 str,這樣的話博主的密文就會被編碼存放(如utf-8),而如果有些位元組無法按utf-8編碼的話,就會引發異常或被忽略。
網上搜了好多文章,均沒有解決博主的問題。
後來還是找到了Official Document
https://docs.python.org/2/library/sqlite3.html#module-sqlite3
原來Python中與sqlite3的BLOB對應的資料類型為buffer,博主驚出一身冷汗,忙看了下自己的插入部分的代碼:
def insertUsernameAndPasswordToDB(conn, cu, username, password):username = encrypt(username)password = encrypt(password)cu.execute("INSERT INTO user(userStudentID, userPassword) VALUES (?,?)", (username, password) )conn.commit()
測試了下username和password的資料類型
print isinstance(username, str)print isinstance(password, str)
結果均為True,怪不得sqlite3嘗試把他們按字串的形式儲存。這裡又涉及一個知識,sqlite3用的是動態資料類型系統,它會按照資料的值來嘗試將資料轉換成資料庫內部的標準類型。這裡它就嘗試將我的位元組串密文轉換成字串。
參考資料:http://www.cnblogs.com/kfqcome/archive/2011/06/27/2137000.html
將username和password轉換成buffer類型,問題解決。
def insertUsernameAndPasswordToDB(conn, cu, username, password):username = encrypt(username)password = encrypt(password)cu.execute("INSERT INTO user(userStudentID, userPassword) VALUES (?,?)", (buffer(username), buffer(password)) )conn.commit()
微博:@浙大宋博