主要处理png图片,其他格式图片也是一样的原理。阅读前可以简略了解一下png格式图片的Data trunck。

首先使用python脚本去掉png的PNG SIG(8 bytes) 以及末尾的PNGIEND(12 bytes)。然后图片剩余数据的每一个字节和秘钥字符串的每一个字符做不进位加(按位异或,解密的原理就是 a ^ b ^ b = a)。通过改写cpp工程里的 Image::initWithImageData(const unsigned char * data, ssize_t dataLen),来进行还原图片数据,也就是解密,过程就是对每一位加密后的数据按秘钥做异或运算还原数据,然后加上PNGSIG和PNGIEND。

加密脚本:(这个脚本会生成加密后的图片替换原始图片)

 # -*- coding:UTF-8 -*-
#该脚本用于加密png图片 使用python3以上版本解释执行
__author__ = "ChenGuanzhou" import os
import time
CUR_DIR = os.getcwd();
print("cur_dir:",CUR_DIR)
#CUR_DIR = 'C:\\Users\\chenguanzhou\\Desktop'
_KEY = 'jiaozi2013' #指定加密秘钥,英文
_ENCRYSIG = 'jiaozhi'
_PNGSIG = bytes([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a])
_PNGIEND = bytes([0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82])
#获取filesig是否是png
def isPNGSig(bytes_8):
return bytes_8 == _PNGSIG def isPNG(absPath):#判断是否是PNG图片
"""
:param absPath: 文件的绝对路径
:return: {Bool}
"""
isFile = os.path.isfile(absPath)
hasPNGSig = False
fileExt = os.path.splitext(absPath)[1]
isPngExt = (fileExt == ".png" or fileExt == ".PNG")
if isFile and isPngExt:
with open(absPath,"rb") as file:
hasPNGSig = isPNGSig(file.read(8)[:8])
return isFile and isPngExt and hasPNGSig def preProcessPng(pngData):#预处理图片数据
"""
剪掉png的signature(8bytes),IEND(12Bytes)
:param pngData:
:return:
"""
assert type(pngData) == bytes
lostHeadData = pngData[8:]
iendData = lostHeadData[-12:]
if iendData == _PNGIEND:#防止Png已经进行过外部软件的压缩,丢掉了IEND
return lostHeadData[:-12]
else:
return lostHeadData def encryption(fileData,key):#加密操作 ascii占一个字节
"""
加密png数据
:param fileData:{bytes}预处理后的png数据
:param key:{str}秘钥
:return:{bytes}加密后的数据
"""
assert type(key) is str
k = bytes(key,"utf8")
klen= len(k)
kindex = 0
fileData = bytearray(fileData)
for i,v in enumerate(fileData):
if kindex >= klen:
kindex = 0
fileData[i] = v ^ k[kindex]#加密
kindex = kindex + 1
return bytes(_ENCRYSIG,"utf8") + fileData #处理图片
def processPNG(filePath):
global filenum
fileData = None
with open(filePath,'rb') as file:
fileData = encryption(preProcessPng(file.read()),_KEY)
os.remove(filePath)
with open(filePath,'wb') as file: #覆盖新文件
file.write(fileData)
filenum = filenum + 1 def traverseDir(absDir):#遍历当前目录以及递归的子目录,找到所有的png图片
"""
:param absDir: 要遍历的路径
:return: None
"""
assert (os.path.isdir(absDir) and os.path.isabs(absDir))
dirName = absDir
for fileName in os.listdir(absDir):
absFileName = os.path.join(dirName,fileName)
if os.path.isdir(absFileName):#递归查找文件夹
traverseDir(absFileName)
elif isPNG(absFileName):
processPNG(absFileName)
else:
pass #------------------- 主函数-------------------------#
start_clock = time.clock()
filenum = 0
#traverseDir(os.path.join(CUR_DIR,"png2"))
traverseDir(CUR_DIR)
end_clock = time.clock()
time = (end_clock - start_clock)*1000
print("encrypt %d Png Pictures"%filenum)
print("use time %fms"%time)

解密的cpp文件

1.新增图片类型

 enum class Format
{
//! JPEG
JPG,
//! PNG
PNG,
//! ENCRYPTEDPNG
ENCRYPTEDPNG, //加密后的Png图片
//! TIFF
TIFF,
//! WebP
WEBP,
//! PVR
PVR,
//! ETC
ETC,
//! S3TC
S3TC,
//! ATITC
ATITC,
//! TGA
TGA,
//! Raw Data
RAW_DATA,
//! Unknown format
UNKNOWN
};

2,修改检测图片类型的Image::detectFormat

 bool Image::isEncryptedPng(const unsigned char * data, ssize_t dataLen){
if (dataLen <= || memcmp("jiaozhi", data, ) != ){
return false;
}
return true;
}
 mage::Format Image::detectFormat(const unsigned char * data, ssize_t dataLen)
{
if (isPng(data, dataLen))
{
return Format::PNG;
}
else if(isEncryptedPng(data,dataLen)){
return Format::ENCRYPTEDPNG;
}
else if (isJpg(data, dataLen))
{
return Format::JPG;
}
else if (isTiff(data, dataLen))
{
return Format::TIFF;
}
else if (isWebp(data, dataLen))
{
return Format::WEBP;
}
else if (isPvr(data, dataLen))
{
return Format::PVR;
}
else if (isEtc(data, dataLen))
{
return Format::ETC;
}
else if (isS3TC(data, dataLen))
{
return Format::S3TC;
}
else if (isATITC(data, dataLen))
{
return Format::ATITC;
}
else
{
return Format::UNKNOWN;
}
}

3.修改Image::initWithImageData,进行解密png

 bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
{
bool ret = false;
do
{
CC_BREAK_IF(! data || dataLen <= ); unsigned char* unpackedData = nullptr;
ssize_t unpackedLen = ; //detect and unzip the compress file
if (ZipUtils::isCCZBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData);
}
else if (ZipUtils::isGZipBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData);
}
else
{
unpackedData = const_cast<unsigned char*>(data);
unpackedLen = dataLen;
} _fileType = detectFormat(unpackedData, unpackedLen); switch (_fileType)
{
case Format::ENCRYPTEDPNG:
{
unsigned char* copyData = new unsigned char[unpackedLen+];//8+12-7
memcpy(copyData + , unpackedData+, unpackedLen-);
deEncryptPng(&copyData, "jiaozi2013", unpackedLen + );
ret = initWithPngData(copyData, unpackedLen + );
delete[] copyData; }
break;
case Format::PNG:
ret = initWithPngData(unpackedData, unpackedLen);
break;
case Format::JPG:
ret = initWithJpgData(unpackedData, unpackedLen);
break;
case Format::TIFF:
ret = initWithTiffData(unpackedData, unpackedLen);
break;
case Format::WEBP:
ret = initWithWebpData(unpackedData, unpackedLen);
break;
case Format::PVR:
ret = initWithPVRData(unpackedData, unpackedLen);
break;
case Format::ETC:
ret = initWithETCData(unpackedData, unpackedLen);
break;
case Format::S3TC:
ret = initWithS3TCData(unpackedData, unpackedLen);
break;
case Format::ATITC:
ret = initWithATITCData(unpackedData, unpackedLen);
break;
default:
{
// load and detect image format
tImageTGA* tgaData = tgaLoadBuffer(unpackedData, unpackedLen); if (tgaData != nullptr && tgaData->status == TGA_OK)
{
ret = initWithTGAData(tgaData);
}
else
{
CCLOG("cocos2d: unsupported image format!");
} free(tgaData);
break;
}
} if(unpackedData != data)
{
free(unpackedData);
}
} while (); return ret;
}

4.新增Image::deEncryptPng做解密:

void Image::deEncryptPng(unsigned char** copyData, const char* key, ssize_t dataLen){
static const unsigned char PNG_SIGNATURE[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
static const unsigned char PNG_IEND[] = { 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 };
unsigned char* _data = *copyData;
memcpy(_data, PNG_SIGNATURE, );
memcpy(_data + (dataLen - ), PNG_IEND, );
unsigned char* de_start = _data + ;
unsigned char* de_end = _data + dataLen - ;
ssize_t keyLen = strlen(key);
ssize_t keyIndex = ;
for (; de_start <= de_end;de_start++,keyIndex++){
if (keyIndex >= keyLen)
keyIndex = ;
*de_start ^= key[keyIndex];
}
}

最后加一句:python大法好。

图片资源的加密和cocos2d-x中的解密的更多相关文章

  1. 如何在cocos2d项目中enable ARC

    如何在cocos2d项目中enable ARC 基本思想就是不支持ARC的代码用和支持ARC的分开,通过xcode中设置编译选项,让支持和不支持ARC的代码共存. cocos2d是ios app开发中 ...

  2. 如何在Cocos2D游戏中实现A*寻路算法(六)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  3. 如何在Cocos2D游戏中实现A*寻路算法(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...

  4. arrays.xml中使用integer-array引用drawable图片资源,代码中如何将这些图片资源赋值到ImageView控件中

    当我们在arrays.xml文件中声明一些图片资源数组的时候: <?xml version="1.0" encoding="utf-8"?> < ...

  5. cocos2d游戏jsc文件格式解密,SpideMonkey大冒险

    “ 介绍cocos2d游戏中常用的jsc格式文件的解密.” 01 — 在破解游戏应用中,经常会碰到后缀为jsc的文件,这是基于cocos2d开发的游戏的加密代码,本质上是js文件,只是被加密了. 例如 ...

  6. Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密

    本文目录 1. 摘要 2. MD5加密封装 3. AES的加密.解密 4. DES加密/解密 5. 总结 1.  摘要 C#中常用的一些加密和解密方案,如:md5加密.RSA加密与解密和DES加密等, ...

  7. ref:使用Dezender对zend加密后的php文件进行解密

    ref:http://www.cnblogs.com/88223100/ 使用Dezender对zend加密后的php文件进行解密   在开发中需要修改一些php文件,部分是通过zend加密的,记事本 ...

  8. jquery对中文进行base64加密,后台用java进行base64解密

    项目中遇到将中文从前台传到后台过程中,出现乱码,一番尝试之后,均是乱码,然后尝试在js代码中先进行base64加密,然后在Java中再进行解密,完美的解决了乱码问题,步骤如下 一,html页面引入jQ ...

  9. RSA Android加密的数据服务器上无法解密?

    一.android加密的数据服务器上无法解密? "算法/模式/填充" android的rsa加密方式是--------RSA/ECB/NoPadding或者RSA/None/NoP ...

  10. python实现RSA加密和签名以及分段加解密的方案

    1.前言 很多朋友在工作中,会遇到一些接口使用RSA加密和签名来处理的请求参数,那么遇到这个问题的时候,第一时间当然是找开发要加解密的方法,但是开发给加解密代码,大多数情况都是java,c++,js等 ...

随机推荐

  1. Linux环境安装Eclipse及配置hadoop插件

    摘要:第一次使用hadoop,另外eclipse也不太熟悉,所以把自己在安装过程中得琐碎记录下来.以备以后查看. 硬软件环境: ▪ 虚拟机: VMware Workstation 11.0.0 bui ...

  2. MongoDB安装及入门

    下载 windows下的是3.2的版本 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/ mongodb采用27 ...

  3. ElasticSearch

    ElaticSearch简介: ES是一个搜索引擎,基于当前最先进,最高效的全功能开源搜索引擎框架lucene ES还有许多功能: 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索 近实时 ...

  4. How to install flashplugin on ubuntu

    sudo apt-get install flashplugin-installer

  5. [原创]Android Lollipop (5.0) 原生代码 Settings 首页加载逻辑分析

    主入口为com.android.settings.Settings. 这只是一个wrapper的类, 它继承于 SettingsActivity类,并且声明了一堆公有的继承于SettingsActiv ...

  6. getStyle(obj, attr)兼容获取css

    设置元素(element)的css属性值可以用element的style属性,dom.style.attr  这样或取得到的值大多数是undefined:何解? dom.style.attr  是用来 ...

  7. MySQL主从同步配置(Ubuntu)

    一.在两台Linux机器上安装MySQL 二.Master主服务器配置(192.168.1.3) 1.编辑my.cnf(命令查找文件位置:find / -name my.cnf) vi /etc/my ...

  8. Codefroces 750D:New Year and Fireworks(BFS)

    http://codeforces.com/contest/750/problem/D 题意:烟花会绽放n次,每次会向前推进t[i]格,每次绽放会向左右45°绽放,问有烟花的格子数. 思路:n = 3 ...

  9. iOS中什么是superView?(新手概念简述版)

    文/司马陶冶(简书作者)/文章有删改原文链接:http://www.jianshu.com/p/8537dac37852 著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 在iPhone ...

  10. ubuntu vim8.0源码安装

    安装篇 从https://github.com/vim/vim下载相应zip源码文件,利用unzip vim-master.zip 命令解压到当前用户目录,即~: 解压后进入vim的src目录,首先, ...