【说明】
这篇文章是对上一篇【Cocos2d-x PNG图片资源加密】的补充和扩展,那篇文章转自【旧时尘安】的博客,文中已经对原理和使用讲解的很清晰,这里只是根据我自己的使用情况做一些小小的功能扩展,也是自己做个整理,以便日后使用。如有侵权,请联系删除。
【链接】
原文地址:http://www.cnblogs.com/zhangpanyi/p/4560297.html
原始工程:https://github.com/zhangpanyi/EncryptPNG
【使用】
修改后的使用有所调整,原文的使用更简洁,这里主要是依照我个人的习惯作出的调整。我在代码中添加了设置密钥和扩展名的接口。
1. 在cocos目录下新建文件夹 ext ,将 CCAES.cpp、CCAES.h、CCDecryptimage.cpp、CCDecryptimage.h 拷贝到其中。
2. 在Xcode项目中引用 ext 目录。
注:这里可能会报错,为此我耽误了半天,结果居然是Xcode没有自动引用导致的,我已记录到【这里】。
3.Android项目需要修改 cocos/AndroID.mk 文件,将两个cpp文件添加进去即可。
4. 在 CCImage 中调用解密代码,方法与原文一样,这里略有修改,代码见附录。
注:我将对 CCDecryptimage.h 的引用放在了 CCImage.h ,是为了在项目中设置密钥时不需要再引用此头文件。
5. 在项目中设置密钥和扩展名,我是在 AppDelegate.cpp 中设置。
注:如果修改扩展名,需要加密端也做修改,保证两边扩展名一致。
[cpp] view plain copy @H_403_60@ //设置密钥 constext::aes_keykey={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; ext::DecryptimageConfig(key,".epng");
【代码】
copy CCImage.cpp
copy boolImage::initWithImagefile(conststd::string&path) { ...... if(!data.isNull()) //图片文件解密 if(ext::AnalyzeExtension(path)[1]==ext::TARGET_EXTENSION) { autoimage_data=ext::Decryptimage(path,data); ret=initWithImageData(&image_data[0],image_data.size()); } else ret=initWithImageData(data.getBytes(),data.getSize()); } #endif//EMSCRIPTEN returnret; boolImage::initWithImagefileThreadSafe(conststd::string&fullpath) if(ext::AnalyzeExtension(fullpath)[1]==ext::TARGET_EXTENSION) autoimage_data=ext::Decryptimage(fullpath,153); Font-weight:bold; background-color:inherit">returnret; }
copy <spanstyle="Font-family:Arial,sans-serif;">CCDecryptimage.h</span>
copy #ifndef__CC_DECRYPT_IMAGE_H__ #define__CC_DECRYPT_IMAGE_H__ #include<array> #include<vector> #include"Ccdata.h" #include"CCAES.h" namespaceext /*解密扩展名*/ staticstd::stringTARGET_EXTENSION=".epng"; /*解密密钥*/ staticaes_keySECRET_KEY={0x31,0x39}; /** *设置解密秘钥 *@paramkey秘钥(AES的16位秘钥) *@paramexten文件扩展名(需要解密的文件扩展名,如".png") */ voIDDecryptimageConfig(constaes_key&key,conststd::string&exten=TARGET_EXTENSION); /** *解密图片文件(在CCImage中调用) *@paramfilename文件名称 *@paramdata文件数据 */ std::vector<unsignedchar>Decryptimage(conststd::string&filename,cocos2d::Data&data); *分解文件名的扩展名(在CCImage中调用) *@paramfile_path文件名 std::array<std::string,2>AnalyzeExtension(conststd::string&file_path); #endif
copy CCDecryptimage.cpp copy #include"CCDecryptimage.h" #include<sstream> #include"ccMacros.h" #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32) #include<WinSock.h> #pragmacomment(lib,"ws2_32.lib") #elif(CC_TARGET_PLATFORM==CC_PLATFORM_IOS||CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID) #include<netinet/in.h> #endif /*CRC码长度*/ staticconstuint32_tCRC_SIZE=4; /*文件头部*/ constunsignedcharhead_DATA[]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a}; /*IENDCRC码*/ charIEND_DATA[]={0xae,0x42,0x60,0x82}; /*数据块头部(用于验证解密是否成功)*/ charBLOCK_head[]={0x45,0x6e,0x63,0x72,0x79,0x70,0x74,0x47}; #pragmapack(push,1) structBlock charname[4]; uint32_tpos; uint32_tsize; }; structIHDRBlock Blockblock; chardata[13+CRC_SIZE]; #pragmapack(pop) /*解析文件扩展名*/ conststd::string&file_path) std::string::size_typepos=file_path.rfind('.'); std::array<std::string,2>text; if(std::string::npos!=pos) text[1]=file_path.substr(pos); text[0]=file_path.substr(0,pos); else text[0]=file_path; returntext; template<int_Value,153); Font-weight:bold; background-color:inherit">typename_Stream> std::array<char,_Value>ReadSome(_Stream&stream) for(unsignedinti=0;i<_Value;++i)buffer[i]=stream.get(); returnbuffer; /*解密块*/ voIDDecryptBlock(std::stringstream&ss,153); Font-weight:bold; background-color:inherit">constaes_key&key) conststd::streamoffcontents_size=ss.tellp()-ss.tellg(); constuint32_tblock_size=(uint32_t)(contents_size+AES_BLOCK_SIZE-contents_size%AES_BLOCK_SIZE); std::vector<uint8_t>buffer; buffer.resize(block_size); for(uint32_ti=0;i<contents_size;++i)buffer[i]=ss.get(); AES::DecryptData(&buffer[0],block_size,key); ss.seekg(0);ss.seekp(0); for(uint32_ti=0;i<block_size;++i)ss.put(buffer[i]); /*解密图片文件*/ CCAssert(!data.isNull(),"dataisnull!"); //获取数据块信息位置 constuint32_tblock_start_pos=ntohl(*reinterpret_cast<uint32_t*>(data.getBytes()+data.getSize()-sizeof(uint32_t))); //获取数据块信息 std::stringstreamblock_info; for(uint32_ti=block_start_pos;i<data.getSize()-sizeof(uint32_t);++i) block_info.put(*(data.getBytes()+i)); //解密数据块信息 DecryptBlock(block_info,SECRET_KEY); //验证数据块信息是否解密成功 autoblock_head=ReadSome<sizeof(BLOCK_head)>(block_info); inti=0;i<block_head.size();++i) if(block_head[i]!=BLOCK_head[i]) CCAssert(false,"thekeyiswrong!"); //写入文件头信息 char>image_data; image_data.reserve(data.getSize()); for(autoch:head_DATA)image_data.push_back(ch); //写入数据块信息 while(true) memcpy(&block,&(ReadSome<sizeof(Block)>(block_info)[0]),153); Font-weight:bold; background-color:inherit">sizeof(Block)); if(block_info.eof()) ""); cclOG("the%sfileformaterror!",filename.c_str()); //写入数据块长度和名称 charsize_buffer[sizeof(block.size)]; memcpy(size_buffer,&block.size,sizeof(size_buffer)); for(autoch:size_buffer)image_data.push_back(ch); for(autoch:block.name)image_data.push_back(ch); block.pos=ntohl(block.pos); block.size=ntohl(block.size); charblock_name[sizeof(block.name)+1]={0}; memcpy(block_name,block.name,153); Font-weight:bold; background-color:inherit">sizeof(block.name)); if(strcmp(block_name,"IHDR")==0) IHDRBlockihdr; memcpy(&ihdr,&block,153); Font-weight:bold; background-color:inherit">sizeof(Block)); memcpy(((char*)&ihdr)+sizeof(Block),&ReadSome<sizeof(IHDRBlock)-sizeof(Block)>(block_info)[0],153); Font-weight:bold; background-color:inherit">for(autoch:ihdr.data)image_data.push_back(ch); else"IEND")==0) for(autoch:IEND_DATA)image_data.push_back(ch); cclOG("decrypt%ssuccess!",153); Font-weight:bold; background-color:inherit">break; for(uint32_ti=0;i<block.size+CRC_SIZE;++i) image_data.push_back(*(data.getBytes()+block.pos+i)); returnimage_data; /*配置解密秘钥和扩展名*/ conststd::string&exten) SECRET_KEY=key; TARGET_EXTENSION=exten; } 总结
以上是内存溢出为你收集整理的【加密】Cocos2d-x PNG图片资源加密(修改版)全部内容,希望文章能够帮你解决【加密】Cocos2d-x PNG图片资源加密(修改版)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)