C/C++通过MySQL的API连接数据库并对数据库中内容RSA解密

来源:互联网 发布:济宁新闻网网络问政 编辑:程序博客网 时间:2024/05/01 15:08

本文对如何使用MySQL的API连接MySQL的数据库,开发环境为VS2010。

1.      VS2010的设置工程

首先,建立一个windows应用程序的工程,将C/C++->预处理器->预处理器定义下的_WINDOWS改为_CONSOLE,将连接器->系统->子系统选择为控制台。

 

将C++常规里面附加包含目录,头文件路径修改

使用API的方式连接,需要加载mysql的头文件和lib文件。在VS2010的附加包含目录中添加\MySQL\MySQL Server 5.1\include。在安装MySql的目录下找。 把libmysql.dll和libmysql.lib文件拷贝到所建的工程目录下。

 

将代码生成里面的运行库改为多线程调试(/MTD


由于我们要使用Mysql的API,并且我们机子上肯定安装了Mysql数据库,所以我们要将工程的头文件路径指向Mysql安装目录的同文件mysql.h所在的位置,将连接库路径指向libmysql.lib所在的路径。


将链接器->输入->附加依赖项中添加libmysql.lib。


改为64位


2.      头文件所需内容

#include"winsock.h"

#include"mysql.h"

#pragma comment(lib,"libmySQL.lib")

3.      MySQL的API接口

mysql_affected_rows()返回被最新的UPDATE, DELETE或INSERT查询影响的行数。

mysql_close()关闭一个服务器连接。

mysql_connect()连接一个MySQL服务器。该函数不推荐;使用mysql_real_connect()代替。

mysql_change_user()改变在一个打开的连接上的用户和数据库。

mysql_create_db()创建一个数据库。该函数不推荐;而使用SQL命令CREATE DATABASE。

mysql_data_seek()在一个查询结果集合中搜寻一任意行。

mysql_debug()用给定字符串做一个DBUG_PUSH。

mysql_drop_db()抛弃一个数据库。该函数不推荐;而使用SQL命令DROP DATABASE。

mysql_dump_debug_info()让服务器将调试信息写入日志文件。

mysql_eof()确定是否已经读到一个结果集合的最后一行。这功能被反对; mysql_errno()或mysql_error()可以相反被使用。

mysql_errno()返回最近被调用的MySQL函数的出错编号。

mysql_error()返回最近被调用的MySQL函数的出错消息。

mysql_escape_string()用在SQL语句中的字符串的转义特殊字符。

mysql_fetch_field()返回下一个表字段的类型。

mysql_fetch_field_direct() 返回一个表字段的类型,给出一个字段编号。

mysql_fetch_fields()返回一个所有字段结构的数组。

mysql_fetch_lengths()返回当前行中所有列的长度。

mysql_fetch_row()从结果集合中取得下一行。

mysql_field_seek()把列光标放在一个指定的列上。

mysql_field_count()返回最近查询的结果列的数量。

mysql_field_tell()返回用于最后一个mysql_fetch_field()的字段光标的位置。

mysql_free_result()释放一个结果集合使用的内存。

mysql_get_client_info()返回客户版本信息。

mysql_get_host_info()返回一个描述连接的字符串。

mysql_get_proto_info()返回连接使用的协议版本。

mysql_get_server_info()返回服务器版本号。

mysql_info()返回关于最近执行得查询的信息。

mysql_init()获得或初始化一个MYSQL结构。

mysql_insert_id()返回有前一个查询为一个AUTO_INCREMENT列生成的ID。

mysql_kill()杀死一个给定的线程。

mysql_list_dbs()返回匹配一个简单的正则表达式的数据库名。

mysql_list_fields()返回匹配一个简单的正则表达式的列名。

mysql_list_processes()返回当前服务器线程的一张表。

mysql_list_tables()返回匹配一个简单的正则表达式的表名。

mysql_num_fields()返回一个结果集合重的列的数量。

mysql_num_rows()返回一个结果集合中的行的数量。

mysql_options()设置对mysql_connect()的连接选项。

mysql_ping()检查对服务器的连接是否正在工作,必要时重新连接。

mysql_query()执行指定为一个空结尾的字符串的SQL查询。

mysql_real_connect()连接一个MySQL服务器。

mysql_real_query()执行指定为带计数的字符串的SQL查询。

mysql_reload()告诉服务器重装授权表。

mysql_row_seek()搜索在结果集合中的行,使用从mysql_row_tell()返回的值。

mysql_row_tell()返回行光标位置。

mysql_select_db()连接一个数据库。

mysql_shutdown()关掉数据库服务器。

mysql_stat()返回作为字符串的服务器状态。

mysql_store_result()检索一个完整的结果集合给客户。

mysql_thread_id()返回当前线程的ID。

mysql_use_result() 初始化一个一行一行地结果集合的检索。

4.      示例程序(该程序为从数据库中读取已通过RSA加密的密文,并解密后输出显示,在VS 2010中运行通过)

#ifndef__MYSQL_INTERFACE_H__

#define__MYSQL_INTERFACE_H__

 

#include"winsock.h"

#include<string>

#include"mysql.h"

#include<vector>

#include<string>

#include<Windows.h>

#include<WinInet.h>

#include<stdio.h>

#include<stdlib.h>

#include<Urlmon.h>

#include<Shlobj.h>

#include<iostream>

#include"randpool.h"

#include"rsa.h"

#include"hex.h"

#include"files.h"

 

#pragmacomment(lib, "ws2_32.lib")

#pragmacomment(lib, "libmysql.lib") //mysql数据库

#pragmacomment(lib, "cryptlib.lib") //cryptlib++

usingnamespace std;

usingnamespace CryptoPP;

 

classMySQLInterface{                   //定义一个MySQL类,专门处理连接、读取数据等功能

 

private:

    MYSQL mysqlInstance;             //MySQL对象,必备的一个数据结构

    MYSQL_RES *result;               //用于存放结果 建议用char* 数组将此结果转存

 

public:

    int errorNum;                    //错误代号

    const char* errorInfo;           //错误提示

 

public:

    MySQLInterface();                                //构造函数

    virtual ~MySQLInterface();            //虚析构函数

 

    bool connectMySQL(char* server, char*username, char* password, char* database,int port);  //数据库连接

    bool createDatabase(std::string&dbname);      //创建数据库

    bool createdbTable(const std::string&query);         //创建数据表

    void errorIntoMySQL();            //数据库错误原因

void closeMySQL();              //关闭数据库,断开连接

    bool writeDataToDB(string queryStr);             //写数据到数据库

    bool getDatafromDB(string queryStr);           //从数据库中读取数据

   

string RSADecryptString(const char*privFilename, const char *ciphertext);                 //RSA解密算法函数

RandomPool & GlobalRNG();      //随机数发生器

 

 

};

#endif

//构造函数 初始化各个变量和数据

MySQLInterface::MySQLInterface():errorNum(0),errorInfo("ok"){

    mysql_library_init(0,NULL,NULL);

    mysql_init(&mysqlInstance);

    mysql_options(&mysqlInstance,MYSQL_SET_CHARSET_NAME,"gbk");

}

 

//析构函数

MySQLInterface::~MySQLInterface(){

 

}

 

//MySQL的连接

boolMySQLInterface::connectMySQL(char* server, char* username, char* password,char* database,int port){

 

   if(mysql_real_connect(&mysqlInstance,server,username,password,database,port,0,0)!= NULL){

           cout<<"==========================="<<endl;

           cout<<"Database connectionsuccess"<<endl;

           cout<<"==========================="<<endl;

           cout<<""<<endl;

        return true;

}

    else

        errorIntoMySQL();

    return false;

}

 

//判断数据库是否存在,不存在则创建数据库,并打开

boolMySQLInterface::createDatabase(std::string& dbname){

 

    std::string queryStr = "createdatabase if not exists ";

    queryStr += dbname;

    if (0 == mysql_query(&mysqlInstance,queryStr.c_str()))

    {

        queryStr = "use ";

        queryStr += dbname;

        if (0 ==mysql_query(&mysqlInstance,queryStr.c_str()))

        {

            return true;

        }

        

    }

    errorIntoMySQL();

    return false;

}

 

//判断数据库中是否存在相应表,不存在则创建表

boolMySQLInterface::createdbTable(const std::string& query){

 

    if (0 ==mysql_query(&mysqlInstance,query.c_str()))

    {

        return true;

    }

    errorIntoMySQL();

    return false;

}

 

//写入数据

bool MySQLInterface::writeDataToDB(stringqueryStr){

 

   if(0==mysql_query(&mysqlInstance,queryStr.c_str()))

        return true;

    else

        errorIntoMySQL();

    return false; 

}

 

//从数据看中读取数据并用RSA解密

boolMySQLInterface::getDatafromDB(string queryStr){        

   if(0!=mysql_query(&mysqlInstance,queryStr.c_str()))   //mysql_query执行指定为一个空结尾的字符串的SQL查询

    {

        errorIntoMySQL();

        return false;

    }

 

   result=mysql_store_result(&mysqlInstance);                    //mysql_store_result检索一个完整的结果集合给客户

 

    int row=mysql_num_rows(result);                                                 //返回一个结果集合中的行的数量

    int field=mysql_num_fields(result);                                       //返回一个结果集合重的列的数量

    MYSQL_ROW line=NULL;   

    line=mysql_fetch_row(result);                                               //从结果集合中取得下一行

 

    int j=0;

    string temp;

    while(NULL!=line)

    { 

        char linedata[1024*100]={0};   //用于存放数据库中行的数据

 

        for(int i=0; i<field;i++)

        {

            if(line[i])

            {

                temp = line[i];

                             strcat(linedata,temp.c_str());          //将timp数组中的内容转换为char型链接至linedata数组后

            }

            else

            {

                temp = "";

                             strcat(linedata,temp.c_str());

            }

        }

        line=mysql_fetch_row(result);

 

           /*--------------------------------------------------------------------*/

           //密文存放在linedata[i]数组中,下面对其分段解密

           char *p =new char[2049];

           int j =0;

 

           for(int i =0;i<strlen(linedata);i++){

                    p[j] = linedata[i];

                    if(j% 2047 == 0 &&j!=0){ //每2048个字符分段一次

                             p[j+1] = '\0';

                             j=0;                             

                             cout<<RSADecryptString("pri",p).c_str();      //边解密,边输出

                             continue;

                    }

                    j++;           

           }                

           /*-------------------------------------------------------------------*/

           cout<<""<<endl;

}

}

 

//随机数产生函数

RandomPool& MySQLInterface::GlobalRNG(){

 

       static RandomPool randomPool;

       return randomPool;

}

 

//RSA解密函数

stringMySQLInterface::RSADecryptString(const char *privFilename, const char*ciphertext){

 

       FileSource privFile(privFilename, true,new HexDecoder);

       RSAES_OAEP_SHA_Decryptor priv(privFile);

 

       string result;

       StringSource(ciphertext, true, newHexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));

       return result;

}

 

//错误信息函数

voidMySQLInterface::errorIntoMySQL(){

    errorNum=mysql_errno(&mysqlInstance);

    errorInfo=mysql_error(&mysqlInstance);

}

 

//断开数据库连接函数

voidMySQLInterface::closeMySQL(){

    mysql_close(&mysqlInstance);

}

 

//主函数

voidmain(){

string pcName;        //存放计算机名数组

MySQLInterface m ;         //实例化一个类

m.connectMySQL("localhost","root","","stat",3306);  //连接数据库

cout<<"Please input pcName:";           

cin>>pcName; //输入用户名

cout<<""<<endl;

cout<<"Success,Pleasewait..."<<endl;

cout<<""<<endl;

m.getDatafromDB("select cmd,result fromcommand where pcFlag ='"+pcName+"'");       //根据输入计算机名查询并解密

cout<<""<<endl<<endl;

cout<<"OK, all the results arealready out, bye bye..."<<endl;

cout<<""<<endl<<endl;

system("pause");

}

5.      运行结果

 

 

图5.1 数据库中是通过RSA加密的数据

 

图5.2 从PHP端加载数据库中信息是密文显示

图5.3运行程序后,成功从数据库中读出数据并解密

 

 

作者:liuzezhong,微信:handsome5533

0 0
原创粉丝点击