亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? zj(3).txt

?? sqlite 3.0使用方法
?? TXT
字號:
(4)              事務處理
sqlite 是支持事務處理的。如果你知道你要同步刪除很多數據,不仿把它們做成一個統一的事務。

通常一次 sqlite3_exec 就是一次事務,如果你要刪除1萬條數據,sqlite就做了1萬次:開始新事務->刪除一條數據->提交事務->開始新事務->… 的過程。這個操作是很慢的。因為時間都花在了開始事務、提交事務上。

你可以把這些同類操作做成一個事務,這樣如果操作錯誤,還能夠回滾事務。

事務的操作沒有特別的接口函數,它就是一個普通的 sql 語句而已:

分別如下:

int result;  

result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //開始一個事務

result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事務

result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //回滾事務

 

一、       給數據庫加密
前面所說的內容網上已經有很多資料,雖然比較零散,但是花點時間也還是可以找到的。現在要說的這個——數據庫加密,資料就很難找。也可能是我操作水平不夠,找不到對應資料。但不管這樣,我還是通過網上能找到的很有限的資料,探索出了給sqlite數據庫加密的完整步驟。

這里要提一下,雖然 sqlite 很好用,速度快、體積小巧。但是它保存的文件卻是明文的。若不信可以用 NotePad 打開數據庫文件瞧瞧,里面 insert 的內容幾乎一覽無余。這樣赤裸裸的展現自己,可不是我們的初衷。當然,如果你在嵌入式系統、智能手機上使用 sqlite,最好是不加密,因為這些系統運算能力有限,你做為一個新功能提供者,不能把用戶有限的運算能力全部花掉。

Sqlite為了速度而誕生。因此Sqlite本身不對數據庫加密,要知道,如果你選擇標準AES算法加密,那么一定有接近50%的時間消耗在加解密算法上,甚至更多(性能主要取決于你算法編寫水平以及你是否能使用cpu提供的底層運算能力,比如MMX或sse系列指令可以大幅度提升運算速度)。

Sqlite免費版本是不提供加密功能的,當然你也可以選擇他們的收費版本,那你得支付2000塊錢,而且是USD。我這里也不是說支付錢不好,如果只為了數據庫加密就去支付2000塊,我覺得劃不來。因為下面我將要告訴你如何為免費的Sqlite擴展出加密模塊——自己動手擴展,這是Sqlite允許,也是它提倡的。

那么,就讓我們一起開始為 sqlite3.c 文件擴展出加密模塊。

 

i.1          必要的宏

通過閱讀 Sqlite 代碼(當然沒有全部閱讀完,6萬多行代碼,沒有一行是我習慣的風格,我可沒那么多眼神去看),我搞清楚了兩件事:

Sqlite是支持加密擴展的;

需要 #define 一個宏才能使用加密擴展。

這個宏就是  SQLITE_HAS_CODEC。

你在代碼最前面(也可以在 sqlite3.h 文件第一行)定義:

#ifndef SQLITE_HAS_CODEC

#define SQLITE_HAS_CODEC

#endif

 

如果你在代碼里定義了此宏,但是還能夠正常編譯,那么應該是操作沒有成功。因為你應該會被編譯器提示有一些函數無法鏈接才對。如果你用的是 VC 2003,你可以在“解決方案”里右鍵點擊你的工程,然后選“屬性”,找到“C/C++”,再找到“命令行”,在里面手工添加“/D "SQLITE_HAS_CODEC"”。

定義了這個宏,一些被 Sqlite 故意屏蔽掉的代碼就被使用了。這些代碼就是加解密的接口。

嘗試編譯,vc會提示你有一些函數無法鏈接,因為找不到他們的實現。

如果你也用的是VC2003,那么會得到下面的提示:

error LNK2019: 無法解析的外部符號 _sqlite3CodecGetKey ,該符號在函數 _attachFunc 中被引用

error LNK2019: 無法解析的外部符號 _sqlite3CodecAttach ,該符號在函數 _attachFunc 中被引用

error LNK2019: 無法解析的外部符號 _sqlite3_activate_see ,該符號在函數 _sqlite3Pragma 中被引用

error LNK2019: 無法解析的外部符號 _sqlite3_key ,該符號在函數 _sqlite3Pragma 中被引用

fatal error LNK1120: 4 個無法解析的外部命令

 

這是正常的,因為Sqlite只留了接口而已,并沒有給出實現。

下面就讓我來實現這些接口。

 

i.2          自己實現加解密接口函數

如果真要我從一份 www.sqlite.org 網上down下來的 sqlite3.c 文件,直接摸索出這些接口的實現,我認為我還沒有這個能力。

好在網上還有一些代碼已經實現了這個功能。通過參照他們的代碼以及不斷編譯中vc給出的錯誤提示,最終我把整個接口整理出來。

實現這些預留接口不是那么容易,要重頭說一次怎么回事很困難。我把代碼都寫好了,直接把他們按我下面的說明拷貝到 sqlite3.c 文件對應地方即可。我在下面也提供了sqlite3.c 文件,可以直接參考或取下來使用。

 

這里要說一點的是,我另外新建了兩個文件:crypt.c和crypt.h。

其中crypt.h如此定義:

#ifndef  DCG_SQLITE_CRYPT_FUNC_

#define  DCG_SQLITE_CRYPT_FUNC_

/***********

董淳光寫的 SQLITE 加密關鍵函數庫

***********/

 

/***********

關鍵加密函數

***********/

int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key );

 

/***********

關鍵解密函數

***********/

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key );

 

#endif

 

 

其中的 crypt.c 如此定義:

#include "./crypt.h"

#include "memory.h"

/***********

關鍵加密函數

***********/

int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )

{

return 0;

}

 

/***********

關鍵解密函數

***********/

int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key )

{

return 0;

}

 

這個文件很容易看,就兩函數,一個加密一個解密。傳進來的參數分別是待處理的數據、數據長度、密鑰、密鑰長度。

處理時直接把結果作用于 pData 指針指向的內容。

你需要定義自己的加解密過程,就改動這兩個函數,其它部分不用動。擴展起來很簡單。

這里有個特點,data_len 一般總是 1024 字節。正因為如此,你可以在你的算法里使用一些特定長度的加密算法,比如AES要求被加密數據一定是128位(16字節)長。這個1024不是碰巧,而是 Sqlite 的頁定義是1024字節,在sqlite3.c文件里有定義:

# define SQLITE_DEFAULT_PAGE_SIZE 1024

你可以改動這個值,不過還是建議沒有必要不要去改它。

 

上面寫了兩個擴展函數,如何把擴展函數跟 Sqlite 掛接起來,這個過程說起來比較麻煩。我直接貼代碼。

分3個步驟。

首先,在 sqlite3.c 文件頂部,添加下面內容:

 

#ifdef SQLITE_HAS_CODEC

#include "./crypt.h"

/***********

用于在 sqlite3 最后關閉時釋放一些內存

***********/

void sqlite3pager_free_codecarg(void *pArg);

#endif

這個函數之所以要在 sqlite3.c 開頭聲明,是因為下面在 sqlite3.c 里面某些函數里要插入這個函數調用。所以要提前聲明。

 

其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函數,要找到它的實現代碼(而不是聲明代碼)。

實現代碼里一開始是:

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT

  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 

  ** malloc() must have already been made by this thread before it gets

  ** to this point. This means the ThreadData must have been allocated already

  ** so that ThreadData.nAlloc can be set.

  */

  ThreadData *pTsd = sqlite3ThreadData();

  assert( pPager );

  assert( pTsd && pTsd->nAlloc );

#endif

 

需要在這部分后面緊接著插入:

 

#ifdef SQLITE_HAS_CODEC

  sqlite3pager_free_codecarg(pPager->pCodecArg);

#endif

 

這里要注意,sqlite3PagerClose 函數大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代碼里搜索“sqlite3PagerClose”是搜不到的。

類似的還有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函數,它們在 pager.h 文件里定義。新版本對應函數是在 sqlite3.h 里定義(因為都合并到 sqlite3.c和sqlite3.h兩文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,這些函數不是消失了,也不是新蹦出來的,而是老版本函數改名得到的。

 

最后,往sqlite3.c 文件下找。找到最后一行:

 

/************** End of main.c ************************************************/

 

在這一行后面,接上本文最下面的代碼段。

這些代碼很長,我不再解釋,直接接上去就得了。

唯一要提的是 DeriveKey 函數。這個函數是對密鑰的擴展。比如,你要求密鑰是128位,即是16字節,但是如果用戶只輸入 1個字節呢?2個字節呢?或輸入50個字節呢?你得對密鑰進行擴展,使之符合16字節的要求。

DeriveKey 函數就是做這個擴展的。有人把接收到的密鑰求md5,這也是一個辦法,因為md5運算結果固定16字節,不論你有多少字符,最后就是16字節。這是md5算法的特點。但是我不想用md5,因為還得為它添加包含一些 md5 的.c或.cpp文件。我不想這么做。我自己寫了一個算法來擴展密鑰,很簡單的算法。當然,你也可以使用你的擴展方法,也而可以使用 md5 算法。只要修改 DeriveKey 函數就可以了。

在 DeriveKey 函數里,只管申請空間構造所需要的密鑰,不需要釋放,因為在另一個函數里有釋放過程,而那個函數會在數據庫關閉時被調用。參考我的 DeriveKey 函數來申請內存。

 

這里我給出我已經修改好的 sqlite3.c 和 sqlite3.h 文件。

如果太懶,就直接使用這兩個文件,編譯肯定能通過,運行也正常。當然,你必須按我前面提的,新建 crypt.h 和 crypt.c 文件,而且函數要按我前面定義的要求來做。


 

i.3          加密使用方法:

現在,你代碼已經有了加密功能。

你要把加密功能給用上,除了改 sqlite3.c 文件、給你工程添加 SQLITE_HAS_CODEC 宏,還得修改你的數據庫調用函數。

前面提到過,要開始一個數據庫操作,必須先 sqlite3_open 。

加解密過程就在 sqlite3_open 后面操作。

假設你已經 sqlite3_open 成功了,緊接著寫下面的代碼:

      int i;

//添加、使用密碼       

      i =  sqlite3_key( db, "dcg", 3 );

      //修改密碼

      i =  sqlite3_rekey( db, "dcg", 0 );

 

用 sqlite3_key 函數來提交密碼。

第1個參數是 sqlite3 * 類型變量,代表著用 sqlite3_open 打開的數據庫(或新建數據庫)。

第2個參數是密鑰。

第3個參數是密鑰長度。

用 sqlite3_rekey 來修改密碼。參數含義同 sqlite3_key。

 

實際上,你可以在sqlite3_open函數之后,到 sqlite3_close 函數之前任意位置調用 sqlite3_key 來設置密碼。

但是如果你沒有設置密碼,而數據庫之前是有密碼的,那么你做任何操作都會得到一個返回值:SQLITE_NOTADB,并且得到錯誤提示:“file is encrypted or is not a database”。

只有當你用 sqlite3_key 設置了正確的密碼,數據庫才會正常工作。

如果你要修改密碼,前提是你必須先 sqlite3_open 打開數據庫成功,然后 sqlite3_key 設置密鑰成功,之后才能用 sqlite3_rekey 來修改密碼。

如果數據庫有密碼,但你沒有用 sqlite3_key 設置密碼,那么當你嘗試用 sqlite3_rekey 來修改密碼時會得到 SQLITE_NOTADB 返回值。

如果你需要清空密碼,可以使用:

//修改密碼

      i =  sqlite3_rekey( db, NULL, 0 );

來完成密碼清空功能。

 

 

i.4         sqlite3.c 最后添加代碼段

 

 

/***

董淳光定義的加密函數

***/

#ifdef SQLITE_HAS_CODEC

 

/***

加密結構

***/

#define CRYPT_OFFSET 8

typedef struct _CryptBlock

{

BYTE*     ReadKey;     // 讀數據庫和寫入事務的密鑰

BYTE*     WriteKey;    // 寫入數據庫的密鑰

int       PageSize;    // 頁的大小

BYTE*     Data;

} CryptBlock, *LPCryptBlock;

 

#ifndef  DB_KEY_LENGTH_BYTE         /*密鑰長度*/

#define  DB_KEY_LENGTH_BYTE   16   /*密鑰長度*/

#endif

 

#ifndef  DB_KEY_PADDING             /*密鑰位數不足時補充的字符*/

#define  DB_KEY_PADDING       0x33  /*密鑰位數不足時補充的字符*/

#endif

 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
精品少妇一区二区三区视频免付费 | 亚洲成在线观看| 麻豆91在线播放免费| 国产a级毛片一区| 欧美日韩一区二区三区在线| 久久久久久久性| 香蕉加勒比综合久久| 99久免费精品视频在线观看| 欧美成人精品福利| 午夜精品在线看| 91亚洲精品久久久蜜桃网站| 精品乱人伦一区二区三区| 亚洲国产日韩a在线播放性色| 成人免费视频视频在线观看免费| 91精品国产麻豆| 亚洲一区二区在线观看视频 | 久久精品在线观看| 日本午夜一本久久久综合| 一本大道综合伊人精品热热| 欧美精品一区二区高清在线观看| 亚洲成人福利片| 色综合天天综合色综合av| 久久久久久久久久久99999| 男女激情视频一区| 欧美久久久久久蜜桃| 亚洲影视在线播放| 91麻豆高清视频| 自拍偷自拍亚洲精品播放| 风间由美一区二区三区在线观看| 日韩欧美国产1| 蜜桃av一区二区| 日韩三级.com| 美女视频一区在线观看| 4438亚洲最大| 免费成人av资源网| 91超碰这里只有精品国产| 午夜精品久久久久久| 制服丝袜中文字幕一区| 成人小视频在线| 2014亚洲片线观看视频免费| 美腿丝袜在线亚洲一区| 日韩三级在线免费观看| 久久av老司机精品网站导航| 精品少妇一区二区三区视频免付费| 裸体健美xxxx欧美裸体表演| 欧美成人精品1314www| 狠狠色丁香婷婷综合| 久久精品这里都是精品| av不卡免费在线观看| 一区二区三区四区不卡在线| 91久久国产最好的精华液| 天涯成人国产亚洲精品一区av| 在线电影欧美成精品| 精品一区二区日韩| 国产精品国产a级| 色成年激情久久综合| 日韩不卡一区二区三区| 欧美精品一区二区三区高清aⅴ| a美女胸又www黄视频久久| 亚洲另类在线制服丝袜| 91精品国产入口| 国产成人在线观看| 亚洲国产欧美日韩另类综合| 日韩午夜在线观看| eeuss鲁一区二区三区| 亚洲一区二区在线免费观看视频| 欧美大片日本大片免费观看| 成人福利电影精品一区二区在线观看| 综合电影一区二区三区| 日韩欧美一级二级三级| 99精品久久99久久久久| 美女性感视频久久| 最新国产成人在线观看| 欧美一二三区精品| 一本大道久久a久久精二百| 日本不卡一二三| 亚洲欧美怡红院| 日韩精品中文字幕一区| 97精品视频在线观看自产线路二| 日韩精品欧美精品| 亚洲欧洲三级电影| 欧美一卡二卡在线观看| 在线看不卡av| 国产成人精品影院| 日本aⅴ精品一区二区三区| 国产精品久久一卡二卡| 日韩精品一区国产麻豆| 91麻豆.com| 国产精品一区二区三区网站| 偷窥少妇高潮呻吟av久久免费 | 91精品久久久久久蜜臀| av一区二区三区黑人| 免费成人性网站| 亚洲一线二线三线久久久| 国产精品天天看| 精品捆绑美女sm三区| 在线综合视频播放| 欧美日韩美女一区二区| 成人av网站大全| 国产精品66部| 精品一区二区三区不卡| 奇米精品一区二区三区四区| 亚洲主播在线观看| 亚洲精品国产一区二区三区四区在线| 国产偷国产偷亚洲高清人白洁| 欧美一级日韩免费不卡| 777xxx欧美| 欧美一区二区福利在线| 欧美精品v国产精品v日韩精品 | 色综合久久中文字幕| 99这里只有精品| 成人爱爱电影网址| 国产超碰在线一区| 成人网在线播放| 99re视频这里只有精品| 99久久免费精品| 91蜜桃婷婷狠狠久久综合9色| 岛国一区二区在线观看| 不卡av在线免费观看| 成人91在线观看| 欧美午夜宅男影院| 欧美精品xxxxbbbb| 日韩欧美国产三级电影视频| 欧美成人猛片aaaaaaa| 久久免费美女视频| 国产精品久久免费看| 亚洲精品一二三| 亚洲国产成人高清精品| 午夜精品久久久久久久久| 欧美96一区二区免费视频| 韩国v欧美v日本v亚洲v| 岛国av在线一区| 欧洲av在线精品| 69p69国产精品| 久久久亚洲精品石原莉奈| 欧美国产欧美亚州国产日韩mv天天看完整| 国产调教视频一区| 日韩美女久久久| 天堂va蜜桃一区二区三区漫画版| 奇米777欧美一区二区| 粉嫩高潮美女一区二区三区| 91视频精品在这里| 69堂亚洲精品首页| 中文字幕欧美日韩一区| 一区二区三区不卡视频在线观看| 亚洲电影一级片| 国产河南妇女毛片精品久久久| 99久久婷婷国产综合精品| 欧美一区二区三区在线| 中文字幕欧美三区| 奇米影视7777精品一区二区| 成人免费高清视频在线观看| 欧美日韩一区 二区 三区 久久精品 | 国产不卡一区视频| 在线观看一区二区精品视频| 日韩精品一区二区三区四区视频| 国产欧美精品一区| 午夜电影网亚洲视频| 成人avav在线| 日韩欧美高清dvd碟片| 国产精品久久久久精k8| 日韩成人一区二区| 91亚洲国产成人精品一区二三| 日韩欧美一区二区免费| 一区二区三区高清| 成人国产视频在线观看| 日韩一级完整毛片| 亚洲你懂的在线视频| 国产高清不卡二三区| 日韩一区二区三区免费看| 亚洲日本韩国一区| 国产成人综合亚洲91猫咪| 日韩欧美国产高清| 亚洲国产日韩一级| 色婷婷激情久久| 国产精品国产馆在线真实露脸| 激情综合五月婷婷| 欧美一区二区三级| 亚洲永久免费av| 色av一区二区| 亚洲欧美精品午睡沙发| 成人av免费在线观看| 久久久久久电影| 精品在线一区二区三区| 69久久夜色精品国产69蝌蚪网| 亚洲欧美电影院| 不卡的看片网站| 精品精品国产高清一毛片一天堂| 免费看欧美女人艹b| 91国产丝袜在线播放| 欧美特级限制片免费在线观看| 亚洲天堂免费在线观看视频| 国产一区二区主播在线| 欧美日产国产精品| 午夜久久福利影院| 欧美午夜一区二区三区| **网站欧美大片在线观看| 99精品一区二区| 欧美激情一区二区三区在线| 麻豆精品在线播放|