From: http://cn.cocos2d-x.org/tutorial/show?ID=2152
C++的Base64算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | /* *base64.cpp * *Createdon:30/04/2011 *Author:nicholas */ #include"base64.h" #include<cctype> //#include<cstdint> #include<algorithm> namespace base64 { namespace { static const std::stringBASE64_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_typec) { 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; else return -1; } } encode_t::encode_t(std::string::size_typesize) :state(zero),remainder(0) { encoded.reserve(encoded_size(size)); } /* Statezero 8bitsinput,zeroremainingfromlast 6bitsconsumed,2remaining =>two Statetwo 8bitsinput,2remainingfromlast 4bitsconsumed,4remaining =>four Statefour 8bitsinput,4remainingfromlast 2bitsconsumed,6remaining 6bitsinput,6remainingfromlast 6bitsconsumed,0remaining =>zero */ voID encode_t::operator()(std::string::value_typec) { 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::stringencode_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_typesize) :state(zero),remainder(0) { decoded.reserve(decoded_size(size)); } /* Statezero 6bitsinput,zeroremainingfromlast 6bitsconsumed,zeroremaining =>six Statesix 6bitsinput,6remainingfromlast write1byte,4remaining =>four Statefour 6bitsinput,4remainingfromlast write1byte,2remaining =>two Statetwo 6bitsinput,2remainingfromlast write1byte,0remaining =>zero */ voID decode_t::operator()(std::string::value_typec) { 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::stringdecode_t::str() const { return decoded; } std::stringencode( const std::string&str) { return std::for_each(str.begin(),str.end(),encode_t(str.size())).str(); } std::stringdecode( 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(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* *base64.h * *Createdon:30/04/2011 *Author:nicholas */ #ifndefBASE64_H_ #defineBASE64_H_ #include<string> namespace base64 { class encode_t { private : enum { zero=0, two, four }state; unsigned int remainder; std::stringencoded; public : encode_t(std::string::size_typesize); voID operator()(std::string::value_typec); std::stringstr(); }; class decode_t { private : enum { zero=0, six, four, two }state; unsigned int remainder; std::stringdecoded; public : decode_t(std::string::size_typesize); voID operator()(std::string::value_typec); std::stringstr() const ; }; /* *Encodethegivenstring@strintoitsbase64representation */ std::stringencode( const std::string&str); /* *Decodethebase64encodedstring@str */ std::stringdecode( const std::string&str); } #endif/*BASE64_H_*/ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include<iostream> #include"base64.h" using namespace std; int main() { stringstr= "abcdefghijklmn." ; stringout=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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | importcom.example.base64.R; importandroID.app.Activity; importandroID.os.Bundle; importandroID.util.Base64; public class MainActivityextendsActivity{ @OverrIDe protected voID onCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentVIEw(R.layout.main); Stringsrc= "abcdefjhijklmn." ; //加密数据 Stringencode=Base64.encodetoString(src.getBytes(),Base64.DEFAulT); //解密数据 Stringdecode= 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库所在目录添加到包含目录中具体路径根据自己项目结构而定
650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="1419573260430321.jpg" alt="20141118150237902.jpg" src="http://API.cocoachina.com/uploads/20141226/1419573260430321.jpg">
3.修改localstorageSetItem方法保存数据时加密数据这里在win32平台下忽略加密 *** 作是因为一般win32平台版本是用于内部测试的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | voID localstorageSetItem( const char *key, const char *value) { assert (_initialized); //加密数据 # if (CC_TARGET_PLATFORM!=CC_PLATFORM_WIN32) //cclOG("key=%ssrc=%s",key,value); std::stringencodeStr=base64::encode(value); value=encodeStr.c_str(); //cclOG("key=%sencode=%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 ( "Errorinlocalstorage.setItem()\n" ); } |
4.修改localstorageGetItem方法获取数据时解密数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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 ( "Errorinlocalstorage.getItem()\n" ); //加密数据 # if (CC_TARGET_PLATFORM!=CC_PLATFORM_WIN32) //cclOG("decodesrc=%s",ret); if (ret) { std::stringdecodeStr=base64::decode(( const char *)ret); char *c= new char ; strcpy_s(c,decodeStr.size()+1,decodeStr.c_str()); //cclOG("key=%sdecode=%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中使用的宏可以看出这个实现在安卓平台下是无法使用的。
650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="1419573173333153.jpg" alt="20141118140919678.jpg" src="http://API.cocoachina.com/uploads/20141226/1419573173333153.jpg">
安卓平台下的实现在cocos2d-x-2.1.5\extensions\localstorage目录下的localstorageAndroID.cpp中。
650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="1419573233692547.jpg" alt="1419573233692547.jpg" border="0" height="117" vspace="0" wIDth="600" src="http://API.cocoachina.com/uploads/20141226/1419573233692547.jpg">
从localStrorageInit的实现可以看出它是通过jni调用了java层中org/cocos2dx/lib/Cocos2dxlocalstorage的静态方法init。
在打包安卓版Cocos2d-x游戏时需要用到引擎的一个java库在cocos2d-x-2.1.5\cocos2dx\platform\androID\java目录下Cocos2dxlocalstorage类就在这个库中。
修改这个类的setItem方法在保存数据的时候加密
1 2 3 4 5 6 7 8 9 10 11 12 | public static voID setItem(Stringkey,Stringvalue){ try { //加密数据 value=Base64.encodetoString(value.getBytes(),Base64.DEFAulT); Stringsql= "replaceinto" +table_name + "(key,value)values(?,?)" ; mDatabase.execsql(sql, new Object[]{key,value}); } catch (Exceptione){ e.printstacktrace(); } } |
修改这个类的getItem方法在获取数据的时候解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public static StringgetItem(Stringkey){ Stringret=null; try { Stringsql= "selectvaluefrom" +table_name+ "wherekey=?" ; Cursorc=mDatabase.rawquery(sql, new String[]{key}); while (c.movetoNext()){ //onlyreturnthefirstvalue if (ret!=null){ Log.e(TAG, "Thekeycontainsmorethanonevalue." ); break ; } ret=c.getString(c.getColumnIndex( "value" )); } c.close(); } catch (Exceptione){ e.printstacktrace(); } //解密数据 if (ret!=null){ ret= new String(Base64.decode(ret,Base64.DEFAulT)); } return ret==null? "" :ret; } |
以上是内存溢出为你收集整理的Cocos2d-x数据加密解密详解全部内容,希望文章能够帮你解决Cocos2d-x数据加密解密详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)