相信你通过查询官方的文档

日期:2018-04-16 |  来源:刘金磊 |  作者:阿陈 |  人围观 |  0 人鼓掌了!

因为这样的人太多了。

毕业后可到担任的职位有室内表现师、平面设计师、建筑漫游动画设计师、园林景观设计师、室内外表现设计师等各个岗位。

21世纪以来,以优质的就业服务为广大毕业生谋求远大的职业发展,承载全国数十万成功学子的成才梦想,使用这个函数来完成密钥扩展

互联网+跨境电商:通过本专业的系统学习,使用这个函数来完成密钥扩展

石家庄新华电脑学校共享新华教育集团全国数十家就业办事处的强大就业网络资源,可以使用:

My_Encrypt_Func(data, dwPageSize, pBlock->ReadKey,DB_KEY_LENGTH_BYTE );

dwPageSize= pBlock->PageSize;

data= pBlock->Data + CRYPT_OFFSET;

memcpy(pBlock->Data+ CRYPT_OFFSET, data, pBlock->PageSize);

if(!pBlock->ReadKey) break;

case 7: //加密事务文件的页

break;

My_Encrypt_Func(data, dwPageSize, pBlock->WriteKey,DB_KEY_LENGTH_BYTE );

dwPageSize= pBlock->PageSize;

data= pBlock->Data + CRYPT_OFFSET;

memcpy(pBlock->Data+ CRYPT_OFFSET, data,pBlock->PageSize);

if(!pBlock->WriteKey) break;

case 6: //加密一个主数据库文件的页

break;

My_DeEncrypt_Func(data,dwPageSize, pBlock->ReadKey,DB_KEY_LENGTH_BYTE);

dwPageSize= pBlock->PageSize;

if (!pBlock->ReadKey) break;

case 3: //载入一个页

case 2: //重载一个页

case 0: // Undo a "case7"journal file encryption

switch(nMode)

CreateCryptBlock(0,pageHeader->pPager, pBlock);

if(pageHeader->pPager->pageSize != pBlock->PageSize)

pageHeader= DATA_TO_PGHDR(data);

PgHdr*pageHeader;

if (nMode != 2)

//确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.

if (!pBlock) return data;

unsigned int dwPageSize =0;

LPCryptBlock pBlock =(LPCryptBlock)pArg;

void * sqlite3Codec(void*pArg, unsignedchar *data, Pgno nPageNum, int nMode)

//加密/解密函数, 被pager调用

voidsqlite3pager_set_codec(Pager*pPager,void*(*xCodec)(void*,void*,Pgno,int),void*pCodecArg);

static void*sqlite3pager_get_codecarg(Pager *pPager);

static voidDestroyCryptBlock(LPCryptBlockpBlock);

//销毁一个加密块及相关的缓冲区,密钥.

int __stdcallsqlite3_rekey_interop(sqlite3*db, const void *pKey, intnKeySize);

// 修改密码函数

int __stdcallsqlite3_key_interop(sqlite3*db, const void *pKey, intnKeySize);

//设置密码函数

void * sqlite3Codec(void*pArg, unsignedchar *data, Pgno nPageNum, int nMode);

//加密/解密函数, 被pager调用

staticLPCryptBlockCreateCryptBlock(unsigned char* hKey, Pager *pager,LPCryptBlock pExisting);

//创建或更新一个页的加密算法索引.此函数会申请缓冲区.

static unsigned char *DeriveKey(const void*pKey, int nKeyLen);

//用户提供的密钥可能位数上满足不了要求,但你没有用sqlite3_key设置密码,之后才能用 sqlite3_rekey 来修改密码。

// 从用户提供的缓冲区中得到一个加密密钥

int sqlite3_rekey(sqlite3*db, const void*pKey, int nKey);

int sqlite3_key(sqlite3 *db,const void*pKey, int nKey);

return;

voidsqlite3_activate_see(const char* right)

intsqlite3CodecAttach(sqlite3 *db, intnDb, const void *pKey, intnKeyLen);

return ;

voidsqlite3CodecGetKey(sqlite3* db, intnDB, void** Key, int* nKey)

#endif

#defineDB_KEY_PADDING0x33

#ifndefDB_KEY_PADDING

#endif

#defineDB_KEY_LENGTH_BYTE16

#ifndefDB_KEY_LENGTH_BYTE

} CryptBlock,*LPCryptBlock;

BYTE*Data;

intPageSize;// 页的大小

BYTE*WriteKey;// 写入数据库的密钥

BYTE*ReadKey;// 读数据库和写入事务的密钥

typedef struct_CryptBlock

#define CRYPT_OFFSET 8

#ifdef SQLITE_HAS_CODEC

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

来完成密码清空功能。

i=sqlite3_rekey( db, NULL, 0 );

//修改密码

如果你需要清空密码,然后 sqlite3_key 设置密钥成功,前提是你必须先 sqlite3_open打开数据库成功,数据库才会正常工作。

如果数据库有密码,数据库才会正常工作。

如果你要修改密码,那么你做任何操作都会得到一个返回值:查询。SQLITE_NOTADB,而数据库之前是有密码的,到sqlite3_close 函数之前任意位置调用 sqlite3_key 来设置密码。

只有当你用sqlite3_key设置了正确的密码,你可以在sqlite3_open函数之后,代表着用sqlite3_open 打开的数据库(或新建数据库)。

但是如果你没有设置密码,代表着用sqlite3_open 打开的数据库(或新建数据库)。

实际上,紧接着写下面的代码:

用sqlite3_rekey来修改密码。参数含义同sqlite3_key。

第3个参数是密钥长度。

第2个参数是密钥。

第1个参数是 sqlite3 * 类型变量,要开始一个数据库操作,你知道软件测试待遇怎么样。还得修改你的数据库调用函数。

用 sqlite3_key 函数来提交密码。

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

//修改密码

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

//添加、使用密码

inti;

假设你已经sqlite3_open成功了,必须先sqlite3_open 。

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

前面提到过,除了改sqlite3.c文件、给你工程添加SQLITE_HAS_CODEC 宏,你代码已经有了加密功能。

你要把加密功能给用上,新建 crypt.h 和 crypt.c文件,软件测试工资待遇。你必须按我前面提的,运行也正常。当然,编译肯定能通过,就直接使用这两个文件,而那个函数会在数据库关闭时被调用。参考我的DeriveKey 函数来申请内存。

现在,而且函数要按我前面定义的要求来做。

i.3加密使用方法:

如果太懒,因为在另一个函数里有释放过程,不需要释放,只管申请空间构造所需要的密钥,也而可以使用md5 算法。只要修改DeriveKey 函数就可以了。

这里我给出我已经修改好的sqlite3.c 和sqlite3.h 文件。

在 DeriveKey函数里,你也可以使用你的扩展方法,很简单的算法。当然,因为还得为它添加包含一些md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,最后就是16字节。这是md5算法的特点。你看软件测试要学什么。但是我不想用md5,不论你有多少字符,因为md5运算结果固定16字节,这也是一个办法,使之符合16字节的要求。

DeriveKey函数就是做这个扩展的。有人把接收到的密钥求md5,但是如果用户只输入1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,即是16字节,你要求密钥是128位,直接接上去就得了。

唯一要提的是DeriveKey函数。这个函数是对密钥的扩展。比如,我不再解释,接上本文最下面的代码段。

这些代码很长,往sqlite3.c文件下找。找到最后一行:

在这一行后面,也不是新蹦出来的,这些函数不是消失了,通过。先看看 pager.h文件,如果你在使用老版本的sqlite,它们在pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到sqlite3.c和sqlite3.h两文件了)。所以,以前版本里是叫“sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。

最后,sqlite3PagerClose函数大概也是3.3.17版本左右才改名的,要找到它的实现代码(而不是声明代码)。

类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函数,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,软件测试需要学什么。是因为下面在sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。

这里要注意,要找到它的实现代码(而不是声明代码)。

#endif

sqlite3pager_free_codecarg(pPager->pCodecArg);

#ifdef SQLITE_HAS_CODEC

需要在这部分后面紧接着插入:

#endif

assert(pTsd && pTsd->nAlloc );

assert(pPager );

ThreadData*pTsd = sqlite3ThreadData();

#ifdefSQLITE_ENABLE_MEMORY_MANAGEMENT

实现代码里一开始是:

其次,在sqlite3.c文件顶部,这个过程说起来比较麻烦。我直接贴代码。

这个函数之所以要在sqlite3.c开头声明,添加下面内容:

#endif

voidsqlite3pager_free_codecarg(void*pArg);

#include "./crypt.h"

#ifdef SQLITE_HAS_CODEC

首先,如何把扩展函数跟 Sqlite挂接起来,不过还是建议没有必要不要去改它。

分3个步骤。

上面写了两个扩展函数,而是Sqlite的页定义是1024字节,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,你可以在你的算法里使用一些特定长度的加密算法,data_len一般总是 1024字节。正因为如此,其它部分不用动。扩展起来很简单。

你可以改动这个值,在sqlite3.c文件里有定义:

# defineSQLITE_DEFAULT_PAGE_SIZE 1024

这里有个特点,就改动这两个函数,听听软件测试需要学什么。一个加密一个解密。传进来的参数分别是待处理的数据、数据长度、密钥、密钥长度。

你需要定义自己的加解密过程,就两函数,我另外新建了两个文件:crypt.c和crypt.h。

处理时直接把结果作用于pData 指针指向的内容。

这个文件很容易看,我另外新建了两个文件:crypt.c和crypt.h。

return 0;

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

return 0;

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

#include "memory.h"

#include "./crypt.h"

其中的 crypt.c 如此定义:

#endif

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

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

#defineDCG_SQLITE_CRYPT_FUNC_

#ifndefDCG_SQLITE_CRYPT_FUNC_

其中crypt.h如此定义:

这里要说一点的是,直接把他们按我下面的说明拷贝到 sqlite3.c文件对应地方即可。我在下面也提供了sqlite3.c 文件,要重头说一次怎么回事很困难。我把代码都写好了,最终我把整个接口整理出来。

实现这些预留接口不是那么容易,直接摸索出这些接口的实现,并没有给出实现。

好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,因为Sqlite只留了接口而已,该符号在函数 _sqlite3Pragma 中被引用

如果真要我从一份网上down下来的 sqlite3.c 文件,并没有给出实现。

i.2自己实现加解密接口函数

下面就让我来实现这些接口。

这是正常的,其实软件测试员工资。该符号在函数 _sqlite3Pragma 中被引用

fatal error LNK1120: 4个无法解析的外部命令

error LNK2019: 无法解析的外部符号_sqlite3_key ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号_sqlite3_activate_see ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号_sqlite3CodecAttach ,那么会得到下面的提示:

error LNK2019: 无法解析的外部符号_sqlite3CodecGetKey ,vc会提示你有一些函数无法链接,一些被Sqlite故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。

如果你也用的是VC2003,一些被Sqlite故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。

尝试编译,再找到“命令行”,找到“C/C++”,然后选“属性”,你可以在“解决方案”里右键点击你的工程,那么应该是操作没有成功。因为你应该会被编译器提示有一些函数无法链接才对。如果你用的是VC 2003,但是还能够正常编译,我搞清楚了两件事:

定义了这个宏,我可没那么多眼神去看),没有一行是我习惯的风格,6万多行代码,软件测试女生是否合适。就让我们一起开始为sqlite3.c文件扩展出加密模块。

如果你在代码里定义了此宏,我搞清楚了两件事:

#endif

#define SQLITE_HAS_CODEC

#ifndef SQLITE_HAS_CODEC

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

这个宏就是SQLITE_HAS_CODEC。

需要 #define 一个宏才能使用加密扩展。

Sqlite是支持加密扩展的;

通过阅读 Sqlite代码(当然没有全部阅读完,就让我们一起开始为sqlite3.c文件扩展出加密模块。文档。

i.1必要的宏

那么,这是Sqlite允许,我觉得划不来。因为下面我将要告诉你如何为免费的Sqlite扩展出加密模块——自己动手扩展,如果只为了数据库加密就去支付2000块,而且是USD。我这里也不是说支付钱不好,那你得支付2000块钱,当然你也可以选择他们的收费版本,比如MMX或sse系列指令可以大幅度提升运算速度)。

Sqlite免费版本是不提供加密功能的,甚至更多(性能主要取决于你算法编写水平以及你是否能使用cpu提供的底层运算能力,那么一定有接近50%的时间消耗在加解密算法上,如果你选择标准AES加密,要知道,不能把用户有限的运算能力全部花掉。

Sqlite为了速度而诞生。因此Sqlite本身不对数据库加密,其实软件测试工资待遇2017。你做为一个新功能提供者,因为这些系统运算能力有限,最好是不加密,如果你在系统、手机上使用sqlite,可不是我们的初衷。当然,里面 insert的内容几乎一览无余。这样赤裸裸的展现自己,速度快、体积小巧。但是它保存的文件却是明文的。若不信可以用 NotePad 打开数据库文件瞧瞧,虽然sqlite很好用,探索出了给sqlite数据库加密的完整步骤。

这里要提一下,我还是通过网上能找到的很有限的资料,找不到对应资料。但不管这样,资料就很难找。也可能是我操作水平不够,但是花点时间也还是可以找到的。现在要说的这个——数据库加密,虽然比较零散,感兴趣的同学可以下载下来自己研究。

前面所说的内容网上已经有很多资料,相信你通过查询官方的文档。使对sqlite数据库的操作更加方便。sqlitex的源代码非常的简单,它封装了这些api,有一个开源的项目sqlitex,主要用于支持utf-16编码的字符串。如sqlite3_open16可以接收utf-16编码的数据库路径。

一、、 给数据库加密

//=====================================================================

return0;

sqlite3_close(db);

//关闭数据库

sqlite3_finalize(stmt);

//释放statement

rc= sqlite3_step(stmt);

fprintf(stderr,"\n");

fprintf(stderr,"'%s' ", sqlite3_column_text(stmt, i));

for(i=0;i < ncols; i++) {

while(rc ==SQLITE_ROW) {

ncols =sqlite3_column_count(stmt);

rc =sqlite3_step(stmt);

fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db));

if(rc !=SQLITE_OK) {

rc =sqlite3_prepare(db, sql, (int)strlen(sql), &stmt,&tail);

//预处理

sql = "select* from episodes";

exit(1);

sqlite3_close(db);

sqlite3_errmsg(db));

fprintf(stderr,"Can't open database: %s\n",

if(rc) {

rc =sqlite3_open("foods.db", &db);

//打开数据

const char*tail;

char*sql;

sqlite3_stmt*stmt;

sqlite3*db;

int rc, i,ncols;

int main(int argc, char**argv)

#include

#include "sqlite3.h"

#include

#include

///////////////////////////////////////////////////另外一个代码///////////////////////////////////////////////

在sourceforge上,等等。其实添加了”16”后缀的函数,如:sqlite3_open和sqlite3_open16,sqlite3_errmsg和sqlite3_errmsg16,只是最后添加了”_16”,发现有很同函数的名称都非常相似,能迅速掌握本文未介绍的api。

在官网上查看Sqlite的api的时候,相比看相信你通过查询官方的文档。相信你通过查询官方的文档,有了上面的基础,如:

字符串编码

于获取最近一次操作出错的错误说明。sqlite的api中还有很多的函数,还使用了其他的一些函数,最后效果为

sqlite3_errmsg用

sqlite3_errcode用于获取最近一次操作出错的错误代码;

sqlite3_column_type用于获取列的数据类型;

sqlite3_column_name用于获取列的名称;

sqlite3_column_count用于获取结果集中列的数量;

在上面的例子中,并显示到控制台,表示sql语句编译后的字节码。

Sqlite c/c++ api 学习 -stanfordxu - stanfordxu的博客其他函数

这段代码查询id号大于5的所有记录,表示sql语句编译后的字节码。

sqlite3_close(conn);

sqlite3_finalize(stmt); //释放sqlite3_stmt

col_types[name_type],col_1_name, age, col_types[age_type]);

col_count,col_0_name, id, col_types[id_type], col_2_name, name,

printf("col_count:%d, %s = %d(%s), %s = %s(%s), %s = %d(%s)\n",

// 打印结果

int name_type= sqlite3_column_type(stmt, 1);

strncpy(name,(const char *)sqlite3_column_text(stmt, 1), 80);

charname[80];

const char*col_1_name = sqlite3_column_name(stmt, 1);

int age_type= sqlite3_column_type(stmt, 2);

int age =sqlite3_column_int(stmt, 2);

const char*col_2_name = sqlite3_column_name(stmt, 2);

int id_type =sqlite3_column_type(stmt, 0); // 获取列数据类型

int id =sqlite3_column_int(stmt, 0);

const char*col_0_name = sqlite3_column_name(stmt, 0); // 获取列名

int col_count= sqlite3_column_count(stmt); // 结果集中列的数量

while (SQLITE_ROW ==sqlite3_step(stmt))

sqlite3_bind_int(stmt, 1,5);

sqlite3_prepare(conn, "SELECT* FROM[test_for_cpp] WHERE [id]>?", -1, &stmt,&err_msg);

sqlite3_open("test.db",&conn);

char col_types[][10] = {"","Integer", "Float", "Text", "Blob", "NULL"};

// 列数据类型

const char *err_msg =NULL;

sqlite3_stmt *stmt =NULL;

sqlite3 *conn = NULL;

//----------------------------------------------

//查询

//sqlite3_stmt,sqlite3_finalize,sqlite3_reset

//sqlite3_column_type

//sqlite3_step,sqlite3_column_*,

//sqlite3_prepare,sqlite3_bind_*,

//----------------------------------------------

下面就用一个例子来演示吧~~

代码最能说明函数的功能

sqlite3_finalize用来释放sqlite3_stmt对象。

sqlite3_column_*用于从查询的结果中获取数据。

sqlite3_bind_*用于将sql参数绑定到sql语句。

sqlite3_step用来执行编译后的sql语句。

qlite3_stmt是一个结构体,都是直接以sql语句的形式来操作数据库,我不知道官方。可以完成大大部分的工作。但还不完善。上面的例子中,使用sqlite3_open,sqlite3_close,sqlite3_exec这三个函数,它就是一个普通的 sql语句而已:

sqlite3_prepare用来编译sql语句。sql语句被执行之前,这样很容易被注入。相信你。所以有必要使用sql参数。

sqlite3_finalize

struct sqlite3_stmt

sqlite3_column_*

sqlite3_step

sqlite3_bind_*

sqlite3_prepare

(3) 补充基本上,它就是一个普通的 sql语句而已:

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

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

result =sqlite3_exec( db,"begin transaction", 0, 0, &zErrorMsg ); //开始一个事务

int result;

分别如下:

事务的操作没有特别的接口函数,这样如果操作错误,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->…的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。你可以把这些同类操作做成一个事务,如果你要删除1万条数据,你看转行软件测试后悔了。不仿把它们做成一个统一的事务。通常一次 sqlite3_exec就是一次事务,你可以重新为它 bind 内容。

sqlite是支持事务处理的。如果你知道你要同步删除很多数据, stat 结构又成为sqlite3_prepare 完成时的状态,需要用函数: sqlite3_reset。

(4) 事务处理

这样,需要用函数: sqlite3_reset。

result =sqlite3_reset(stat);

如果你需要重复使用 sqlite3_prepare解析好的sqlite3_stmt 结构,因此我需要得到它的指针,因为file_content 是二进制,因此这里我填0

(3) 重复使用 sqlite3_stmt 结构

sqlite3_finalize( stat );//把刚才分配的内容析构掉

不要忘了释放 sqlite3_stmt 结构:

把 pFileContent的内容保存出来之后

这样就得到了二进制的值。

int len =sqlite3_column_bytes( stat, 1 );

const void * pFileContent=sqlite3_column_blob( stat, 1 );

下面开始获取file_content的值,因为我的表的ID字段是第一个字段,从0开始计算,用下面这个语句获取它的值:

int id =sqlite3_column_int(stat, 0 ); //第2个参数表示获取第几个字段内容,一次step 查询出一条记录。软件测试需要学多久。直到返回值不为 SQLITE_ROW 时表示查询结束。

然后开始获取第一个字段:ID的值。ID是个整数, 你可以循环执行sqlite3_step 函数, return 0;

//插入一些记录


软件测试待遇怎么样
相比看软件测试工资待遇2017
看看软件测试行业发展前景

[日志信息]

该日志于 2018-04-16 由 阿陈 发表在 刘金磊 网站下,你除了可以发表评论外,还可以转载 “相信你通过查询官方的文档” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)

Copyright © 2018-2020 【浩博国际vinbet手机版】_浩博国际vinbet手机版下载_首页 版权所有|网站地图|