【转】【加密】Cocos2d-x PNG图片资源加密

转载地址:http://blog.csdn.net/ldpjay/article/details/46438157

原文地址:http://www.cnblogs.com/zhangpanyi/p/4560297.html

工程地址:https://github.com/zhangpanyi/EncryptPNG


实现原理

    如果你对实现原理并不感兴趣,只是想直接使用的话可以跳过这节。首先我假设读者已经清楚PNG图像文件结构了,如果没有的话这里建议可以看看《揭秘数据解密的关键技术》第5章,这章里面专门对PNG图像格式进行了介绍。或者看看《PNG文件格式详解》这篇文章。

    实现原理很简单,只是将PNG文件的文件头和每个数据块的名称给去掉,特殊的数据块(如IHDR和IEND)连数据块内容也一并给去掉。在这之后,已经找不到PNG的特征信息了。但是要怎么解密呢?我将去掉的那些信息按照一定格式保存起来,然后进行AES加密,最后把加密后的数据追加到文件尾,必须要密钥正确的情况下才能解密成功。这样做好处就是解密的效率高。一个文件大概只需加密几十字节,而不必加密整个文件,这将大大提升解密时的速度。

如何使用

    首先说一下加密解密最简单的方法。先去这里下载我已经编译好的加密和解密程序,如果无法运行你可以自己编译源代码来生成程序(必须要支持C++11的编译器)。

    要加密PNG图片,就把 EncryptPNG.exe 文件放到图片所在的文件目录里面执行,然后输入密钥就可以了。然后它就会自动加密所在目录及其子目录的所有PNG图片,并在生成对应的 .epng 文件。

    如果想要验证文件是否能够成功解密,只需打开命令窗口,输入 DecryptPNG.exe xxx.epng,然后输入密钥。如果密钥正确的话就会生成一个 .png 文件。这都很简单吧?

在cocos2d-x 上的使用

    在cocos2d-x上的使用更为简单,就跟平时创建精灵的方法是一样的。例如:

[cpp]  view plain  copy
  1. // add "HelloWorld" splash screen"  
  2. auto sprite = Sprite::create("HelloWorld.epng");  
  3.   
  4. // position the sprite on the center of the screen  
  5. sprite->setPosition(Vec2(visibleSize / 2) + origin);  
  6.   
  7. // add the sprite as a child to this layer  
  8. this->addChild(sprite);  

就跟使用普通的PNG图片一样吧?不过在这之前你需要修改一下引擎代码。这里以cocos2d-x 3.6 为例,首先下载这些文件 。然后把里面的所有文件拷贝到cocos2d\cocos\base 目录下,在cocos2d\cocos\Android.mk的 LOCAL_SRC_FILES 里面添加 base/CCAES.cpp 和 base/CCDecryptImage.cpp。最后还需要做一件事情,编辑cocos2d\cocos\platform\CCImage.cpp文件,添加头文件 #include "base/CCDecryptImage.h" ,然后修改 initWithImageFile 和 initWithImageFileThreadSafe 函数,将 if (!data.isNull()) 里面的内容替换成下面的:


[cpp]  view plain  copy
  1. bool Image::initWithImageFile(const std::string& path)  
  2. {  
  3.     bool ret = false;  
  4.     _filePath = FileUtils::getInstance()->fullPathForFilename(path);  
  5.   
  6. #ifdef EMSCRIPTEN  
  7.     // Emscripten includes a re-implementation of SDL that uses HTML5 canvas  
  8.     // operations underneath. Consequently, loading images via IMG_Load (an SDL  
  9.     // API) will be a lot faster than running libpng et al as compiled with  
  10.     // Emscripten.  
  11.     SDL_Surface *iSurf = IMG_Load(fullPath.c_str());  
  12.   
  13.     int size = 4 * (iSurf->w * iSurf->h);  
  14.     ret = initWithRawData((const unsigned char*)iSurf->pixels, size, iSurf->w, iSurf->h, 8, true);  
  15.   
  16.     unsigned int *tmp = (unsigned int *)_data;  
  17.     int nrPixels = iSurf->w * iSurf->h;  
  18.     for(int i = 0; i < nrPixels; i++)  
  19.     {  
  20.         unsigned char *p = _data + i * 4;  
  21.         tmp[i] = CC_RGB_PREMULTIPLY_ALPHA( p[0], p[1], p[2], p[3] );  
  22.     }  
  23.   
  24.     SDL_FreeSurface(iSurf);  
  25. #else  
  26.     Data data = FileUtils::getInstance()->getDataFromFile(_filePath);  
  27.   
  28.     if (!data.isNull())  
  29.     {  
  30.         if (splitext(path)[1] == ".epng")  
  31.         {  
  32.             auto image_data = DecryptImage(path, data);  
  33.             ret = initWithImageData(&image_data[0], image_data.size());  
  34.         }  
  35.         else  
  36.         {  
  37.             ret = initWithImageData(data.getBytes(), data.getSize());  
  38.         }  
  39.     }  
  40. #endif // EMSCRIPTEN  
  41.   
  42.     return ret;  
  43. }  
  44.   
  45. bool Image::initWithImageFileThreadSafe(const std::string& fullpath)  
  46. {  
  47.     bool ret = false;  
  48.     _filePath = fullpath;  
  49.   
  50.     Data data = FileUtils::getInstance()->getDataFromFile(fullpath);  
  51.   
  52.     if (!data.isNull())  
  53.     {  
  54.         if (splitext(fullpath)[1] == ".epng")  
  55.         {  
  56.             auto image_data = DecryptImage(fullpath, data);  
  57.             ret = initWithImageData(&image_data[0], image_data.size());  
  58.         }  
  59.         else  
  60.         {  
  61.             ret = initWithImageData(data.getBytes(), data.getSize());  
  62.         }  
  63.     }  
  64.   
  65.     return ret;  
  66. }  

好了大功告成。密钥在CCDecryptImage.cpp文件 DEAULT_KEY 里设置(默认是123456),现在可以运行最开始的那段代码试试能否成功解密了。

源码下载

C++实现的加密和解密的源码

https://github.com/zhangpanyi/EncryptPNG/tree/master/cpp

原文地址:http://www.cnblogs.com/zhangpanyi/

参考文章: http://cn.cocos2d-x.org/tutorial/show?id=2908
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值