Cocos2d-x数据加密解密详解

Cocos2d-x数据加密解密详解,第1张

概述C++的Base64算法实现 /* * base64.cpp * * Created on: 30/04/2011 * Author: nicholas */#include "base64.h"#include <cctype>//#include <cstdint>#include <algorithm>namespace base64{namespace

C++的Base64算法实现

/* * base64.cpp * *  Created on: 30/04/2011 *      Author: nicholas */#include "base64.h"#include <cctype>//#include <cstdint>#include <algorithm>namespace base64{namespace{static const std::string BASE64_CHARS = "ABCDEFGHIJKLMnopQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";size_t encoded_size(size_t raw){switch((raw*8)%6){case 0:return (raw*8)/6;case 2:return ((raw*8)/6) + 3;case 4:return ((raw*8)/6) + 2;}return raw;}size_t decoded_size(size_t unpadded){return (unpadded*6)/8;}int base64_index(std::string::value_type c){if(c >= 'A' && c <= 'Z')return c-'A';else if(c >= 'a' && c <= 'z')return c-'a' + 26;else if(c >= '0' && c <= '9')return c-'0' + 52;else if(c == '+')return 62;else if(c == '/')return 63;elsereturn -1;}}encode_t::encode_t(std::string::size_type size) : state(zero),remainder(0){encoded.reserve(encoded_size(size));}/*State zero8 bits input,zero remaining from last6 bits consumed,2 remaining=> twoState two8 bits input,2 remaining from last4 bits consumed,4 remaining=> fourState four8 bits input,4 remaining from last2 bits consumed,6 remaining6 bits input,6 remaining from last6 bits consumed,0 remaining=> zero */voID encode_t::operator() (std::string::value_type c){unsigned char value(0);switch(state){case zero:value = (c & 0xfc) >> 2;remainder = c & 0x3;encoded.push_back(BASE64_CHARS[value]);state = two;break;case two:value = (remainder << 4) | ((c & 0xf0) >> 4);remainder = c & 0xf;encoded.push_back(BASE64_CHARS[value]);state = four;break;case four:value = (remainder << 2) | ((c & 0xc0) >> 6);remainder = c & 0x3f;encoded.push_back(BASE64_CHARS[value]);value = remainder;encoded.push_back(BASE64_CHARS[value]);state = zero;break;}}std::string encode_t::str(){unsigned char value(0);switch(state){case zero:break;case two:value = remainder << 4;encoded.push_back(BASE64_CHARS[value]);encoded.push_back('=');encoded.push_back('=');state = zero;break;case four:value = remainder << 2;encoded.push_back(BASE64_CHARS[value]);encoded.push_back('=');state = zero;break;}return encoded;}decode_t::decode_t(std::string::size_type size) : state(zero),remainder(0){decoded.reserve(decoded_size(size));}/*State zero6 bits input,zero remaining=> sixState six6 bits input,6 remaining from lastwrite 1 byte,4 remaining=> fourState four6 bits input,4 remaining from lastwrite 1 byte,2 remaining=> twoState two6 bits input,2 remaining from lastwrite 1 byte,0 remaining=> zero */voID decode_t::operator() (std::string::value_type c){unsigned char value(0);int index = base64_index(c);if(index == -1)return;switch(state){case zero:remainder = index;state = six;break;case six:value = (remainder << 2) | ((index & 0x30) >> 4);remainder = index & 0xf;decoded.push_back(value);state = four;break;case four:value = (remainder << 4) | ((index & 0x3c) >> 2);remainder = index & 0x3;decoded.push_back(value);state = two;break;case two:value = (remainder << 6) | index;decoded.push_back(value);state = zero;break;}}std::string decode_t::str() const{return decoded;}std::string encode(const std::string& str){return std::for_each(str.begin(),str.end(),encode_t(str.size())).str();}std::string decode(const std::string& str){size_t unpadded_size = str.size();if(str.size() > 0 && str[str.size()-1] == '=')unpadded_size -= 1;if(str.size() > 1 && str[str.size()-2] == '=')unpadded_size -= 1;return std::for_each(str.begin(),decode_t(unpadded_size)).str();}}
/* * base64.h * *  Created on: 30/04/2011 *      Author: nicholas */#ifndef BASE64_H_#define BASE64_H_#include <string>namespace base64{class encode_t{private:enum{zero = 0,two,four} state;unsigned int remainder;std::string encoded;public:encode_t(std::string::size_type size);voID operator() (std::string::value_type c);std::string str();};class decode_t{private:enum{zero = 0,six,four,two} state;unsigned int remainder;std::string decoded;public:decode_t(std::string::size_type size);voID operator() (std::string::value_type c);std::string str() const;};/* * Encode the given string @str into its base64 representation */std::string encode(const std::string& str);/* * Decode the base64 encoded string @str */std::string decode(const std::string& str);}#endif /* BASE64_H_ */

#include<iostream>#include"base64.h"using namespace std;int main (){    string str = "abcdefghijklmn.";    string out = base64::encode(str);        cout<<"src:"<<str<<endl;     cout<<"encode: "<<out<<endl;    cout<<"decode: "<<base64::decode(out)<<endl;              str = "中文.";    out = base64::encode(str);        cout<<endl<<"src:"<<str<<endl;    cout<<"encode: "<< out <<endl;    cout<<"decode: "<< base64::decode(out) <<endl;         system("pause");    return 1;    }

AndroID平台下使用Base64算法加密解密数据


import com.example.base64.R;import androID.app.Activity;import androID.os.Bundle;import androID.util.Base64;public class MainActivity extends Activity {    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.main);        String src = "abcdefjhijklmn.";        // 加密数据        String encode = Base64.encodetoString(src.getBytes(),Base64.DEFAulT);        // 解密数据        String decode = new String(Base64.decode(encode,Base64.DEFAulT));        System.out.println("src:" + src);        System.out.println("encode:" + encode);        System.out.println("decode:" + decode);    }}

数据库数据项加密

Cocos2d-x中 *** 作数据库的实现都封装在localstorage这个类中。使用的是sqlite3。


iOS、Win32平台的加密

1.base64.h和base64.cpp添加项目Classes目录下。

2.右键libExtensions项目,附加包含目录,把base64库所在目录添加到包含目录中,具体路径根据自己项目结构而定


3.修改localstorageSetItem方法,保存数据时加密数据,这里在win32平台下忽略加密 *** 作是因为一般win32平台版本是用于内部测试的

@H_301_49@voID localstorageSetItem( const char *key,const char *value) { assert( _initialized ); // 加密数据 #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) //cclOG("key=%s src=%s",key,value); std::string encodeStr = base64::encode(value); value = encodeStr.c_str(); //cclOG("key=%s encode=%s",value); #endif int ok = sqlite3_bind_text(_stmt_update,1,-1,sqlITE_TRANSIENT); ok |= sqlite3_bind_text(_stmt_update,2,value,sqlITE_TRANSIENT); ok |= sqlite3_step(_stmt_update); ok |= sqlite3_reset(_stmt_update); if( ok != sqlITE_OK && ok != sqlITE_DONE) printf("Error in localstorage.setItem()\n"); }
4.修改localstorageGetItem方法,获取数据时解密数据
const char* localstorageGetItem( const char *key )  {      assert( _initialized );         int ok = sqlite3_reset(_stmt_select);         ok |= sqlite3_bind_text(_stmt_select,sqlITE_TRANSIENT);      ok |= sqlite3_step(_stmt_select);      const unsigned char *ret = sqlite3_column_text(_stmt_select,0);                if( ok != sqlITE_OK && ok != sqlITE_DONE && ok != sqlITE_ROW)          printf("Error in localstorage.getItem()\n");         // 加密数据      #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)          //cclOG("decode src=%s",ret);            if (ret)          {              std::string decodeStr = base64::decode((const char*)ret);                                                    char* c = new char;                           strcpy_s(c,decodeStr.size() + 1,decodeStr.c_str());                //cclOG("key=%s decode=%s",c);                          return c;          }             #endif         return (const char*)ret;  }

注意:c_str()方法返回的是string对象中保留的字符串指针,该指针的生命周期是跟随string对象的。也就是如果直接返回decodeStr.c_str(),返回的将是垃圾数据,因为decodeStr在函数结束后,已经被销毁了,指针所指向的是垃圾数据。


这种数据库加密方案存在以下几个问题:

1.如果别人知道我所使用的加密算法,然后通过程序计算出加密串,还是可以修改成功的。

2.数据库还是可以用相关工具打开,并查看数据表。

3.每次读写数据时,增加了加密解密的步骤,降低效率。


对于Cocos2d-x中数据库的加密有更好的解决办法,就是使用wxsqlite3,点击查看【集成wxSqlite3到Cocos2d-x】,这种数据库加密的实现是在初始化数据库的时候加密,运行时加载数据库时候调用相关API解密,加载完成后数据的读写效率和未加密时一样,相对比较高效。

AndroID平台的加密

从localstorage.cpp中使用的宏可以看出,这个实现在安卓平台下是无法使用的。



安卓平台下的实现在:cocos2d-x-2.1.5\extensions\localstorage目录下的localstorageAndroID.cpp中。

从localStrorageInit的实现可以看出,它是通过jni调用了java层中org/cocos2dx/lib/Cocos2dxlocalstorage的静态方法init。

在打包安卓版Cocos2d-x游戏时需要用到引擎的一个java库,在cocos2d-x-2.1.5\cocos2dx\platform\androID\java目录下,Cocos2dxlocalstorage类就在这个库中。

修改这个类的setItem方法,在保存数据的时候加密
public static voID setItem(String key,String value) {      try {          // 加密数据          value = Base64.encodetoString(value.getBytes(),Base64.DEFAulT);             String sql = "replace into " + table_name                  + "(key,value)values(?,?)";          mDatabase.execsql(sql,new Object[] { key,value });      } catch (Exception e) {          e.printstacktrace();      }  }

修改这个类的getItem方法,在获取数据的时候解密
public static String getItem(String key) {      String ret = null;      try {          String sql = "select value from " + table_name + " where key=?";          Cursor c = mDatabase.rawquery(sql,new String[] { key });          while (c.movetoNext()) {              // only return the first value              if (ret != null) {                  Log.e(TAG,"The key contains more than one value.");                  break;              }              ret = c.getString(c.getColumnIndex("value"));          }          c.close();      } catch (Exception e) {          e.printstacktrace();      }             // 解密数据      if (ret != null) {          ret = new String(Base64.decode(ret,Base64.DEFAulT));      }             return ret == null ? "" : ret;  }

来源网址:http://www.jb51.cc/article/p-ygjicaym-bea.html

总结

以上是内存溢出为你收集整理的Cocos2d-x数据加密解密详解全部内容,希望文章能够帮你解决Cocos2d-x数据加密解密详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1055566.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存