博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用python对cocos2dx的手游图片资源进行加密
阅读量:2303 次
发布时间:2019-05-09

本文共 4189 字,大约阅读时间需要 13 分钟。

转自:http://blog.csdn.net/liuhannan111/article/details/52472012

使用python对cocos2dx的手游图片资源进行加密


导言

由于项目的需要,要对游戏的图片资源进行加密,目前比较常用的做法应该是使用TexturePacker的加密功能。但因为我们的整个打包流程都是python脚本控制,自动化完成的,如果要使用TexturePacker的加密功能,就要把TexturePacker的命令行工具集成到整个自动化打包工具中。考虑到工作量会比较大,所以决定采用在图片压缩后自动遍历assets目录下的所有的图片并使用python自动进行字节流加密的解决方案。缺点是加密方式比较简单,易于破解。


步骤

1.编写python加密模块

加密模块的大致思路就是以2进制可读的方式打开图片资源文件,然后遍历字节流,对每个字节进行一定的转化,我采用的是异或一个随机的值,然后在整个文件的头部加上三个字节的标识,用来标识这个图片是否进行了加密处理。然后第四个字节保存加密的密钥。最后将二进制数据流写入一个新的图片文件,同时删除老的图片文件。图片的加密过程到此就结束了。

######################################### __encrypt__.py# 功能:对png、jpg进行加密处理# 作者:刘翰男# 创建:2016-09-01########################################import osimport sysimport randomprint("__encrypt__.py")#随机生成密匙random.randint(1, 255)encrypt_key = random.randint(1, 255)#加密过的标示,两个字节have_encrypt_first_flag = 0x12have_encrypt_second_flag = 0x34have_encrypt_third_flag = 0x56#images_path是需要加密的图片的绝对路径def encrypt(images_path):    f = open(images_path, 'rb')    filedata = f.read()    filesize = f.tell()    f.close()    file_byte_array = bytearray(filedata)    #判断是否加密过    if(have_encrypt_first_flag == file_byte_array[0]        and have_encrypt_second_flag == file_byte_array[1]        and have_encrypt_third_flag == file_byte_array[2]):            print('this png has encrypt before!')    else:        encrypt_file_byte_array = bytearray(0)        encrypt_file_byte_array.append(have_encrypt_first_flag)        encrypt_file_byte_array.append(have_encrypt_second_flag)        encrypt_file_byte_array.append(have_encrypt_third_flag)        encrypt_file_byte_array.append(encrypt_key)        for byte in file_byte_array:            encrypt_bype = byte ^ encrypt_key            encrypt_file_byte_array.append(encrypt_bype)        workdir = os.path.split(images_path)[0]        os.remove(images_path)        f2 = open(images_path,'wb')        f2.write(encrypt_file_byte_array)        f2.close()#判断是否是png和jpg图片def judge_is_png_or_jpg(file_name):    suffix = os.path.splitext(file_name)[1]    if  suffix== '.png' or suffix == '.jpg' or suffix == '.PNG' or suffix == '.JPG':        return True    else:        return False

2.修改cocos2dx引擎

我们知道,所有的资源文件,都要先从磁盘读到内存。我们要修改的就是读取的这个过程。打开cocos2dx引擎源码文件CCImage.cpp,找到initWithImageFile(const std::string& path)这个方法。修改前的源代码如下:

bool Image::initWithImageFile(const std::string& path){    bool ret = false;    _filePath = FileUtils::getInstance()->fullPathForFilename(path);    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);    if (!data.isNull())    {        auto bin = data.getBytes();        auto size = data.getSize();        ret = initWithImageData(data.getBytes() + encrypt_head_lengh, data.getSize());    }    return ret;}

这个方法是读取图片文件,然后获取byte数据流,并用这些数据初始化形成图片,现在我们要做的就是在获取到这些二进制数据之后,进行解密。 
1. 获取前三个字节,如果是加密标识的话,表明这个图片已经进行了,加密处理,在此则要进行解密处理。 
2. 取第四个字节,也就是对当前这个图片进行加密时的密钥,拿这个密钥进行解密。 
3. 用解密后的字节流初始化形成图片。

修改后的源代码如下:

bool Image::initWithImageFile(const std::string& path){    bool ret = false;    _filePath = FileUtils::getInstance()->fullPathForFilename(path);    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);    if (!data.isNull())    {        auto bin = data.getBytes();        auto size = data.getSize();        unsigned char have_encrypt_first_flag = *bin;        unsigned char have_encrypt_second_flag = *(bin + 1);        unsigned char have_encrypt_third_flag = *(bin + 2);        unsigned char encrypt_key = 0;        unsigned int encrypt_head_flag_lengh = 3;        unsigned int encrypt_head_lengh = 4;        if (have_encrypt_first_flag == 0x12            && have_encrypt_second_flag == 0x34            && have_encrypt_third_flag == 0x56)        {            encrypt_key = *(bin + encrypt_head_flag_lengh);            auto *cur = bin + encrypt_head_lengh;            auto count = size - encrypt_head_lengh;            while (count)            {                *cur ^= encrypt_key;                ++cur;                --count;            }            ret = initWithImageData(data.getBytes() + encrypt_head_lengh, data.getSize());        }        else        {            ret = initWithImageData(data.getBytes(), data.getSize());        }    }    return ret;}

PS:小知识

int a = 0x1121;int b = 0x21;int c = a^b;再用c^b会发现等于a。

你可能感兴趣的文章
702. Search in a Sorted Array of Unknown Size
查看>>
658. Find K Closest Elements
查看>>
852. Peak Index in a Mountain Array
查看>>
153. Find Minimum in Rotated Sorted Array
查看>>
109. Convert Sorted List to Binary Search Tree
查看>>
116. Populating Next Right Pointers in Each Node
查看>>
138. Copy List with Random Pointer
查看>>
912. Sort an Array
查看>>
148. Sort List
查看>>
350. Intersection of Two Arrays II
查看>>
347. Top K Frequent Elements
查看>>
503. Next Greater Element II
查看>>
543. Diameter of Binary Tree
查看>>
560. Subarray Sum Equals K
查看>>
572. Subtree of Another Tree
查看>>
深入理解计算机系统(CSAPP) 第一章学习笔记
查看>>
深入理解计算机系统(CSAPP) 第二章学习笔记
查看>>
1. Two Sum
查看>>
深拷贝和浅拷贝
查看>>
2. Add Two Numbers
查看>>