圖片、json等文本文件加密|cocos creator相關

直入主題。

加密

加密腳本是python3寫的,直接貼上來:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os,sys
import os.path
# import filetype

encodeKey = ''

def moveFile(infile, outfile):
    inBuffer = ""
    with open(infile, "rb+") as fr:
        inBuffer = fr.read()
    with open(outfile, "wb+") as fw:
        fw.write(inBuffer)

# 加密
def encodeFile(infile, outfile):
    inBuffer = ''
    key = getEncodeKey().encode("UTF-8")
    outBuffer = []
    for b in key:
        outBuffer.append(b)
    with open(infile, 'rb+') as fr:
        inBuffer = fr.read()
    idx = 0
    for b in inBuffer:
        eb = b ^ key[idx % len(key)] # 按位異或,這裏就是加密操作了
        outBuffer.append(eb)
        idx = idx + 1
    # print(inBuffer, len(inBuffer))
    # print(bytes(outBuffer), len(outBuffer))
    if (len(outBuffer) - len(inBuffer)) != len(key):
        print("length: %d, out: %d,  outfile: %s" % (len(inBuffer), len(outBuffer), bytes(outBuffer)))
    with open(outfile,'wb+') as fw:
        fw.write(bytes(outBuffer))  #這裏要用bytes數組存入,如果轉爲字符串的話,解密會有問題

# 加密路徑下文件
def encodeDir(rootdir, outDir):
    for parent,dirnames,filenames in os.walk(rootdir):
        if len(filenames) > 0:
            for filename in filenames:
                files = filename.partition(".")
                inPath=os.path.join(parent,filename)
                outDir2 = outDir+parent.replace(rootdir, "")
                if not os.path.exists(outDir2):
                    os.makedirs(outDir2)
                outPath=os.path.join(outDir2, filename)
                print("outFile: %s" % outPath)
                if len(files) > 2:
                    if files[len(files)-1] == "png" or files[len(files)-1] == "jpg" or files[len(files)-1] == "json":
                        encodeFile(inPath, outPath)
                    else:
                        moveFile(inPath, outPath)

def getEncodeKey():
    return encodeKey

print(len(sys.argv))
if len(sys.argv) != 4:
    if len(sys.argv) < 2:
        print('缺少加密路徑')
    elif len(sys.argv) < 3:
        print('缺少輸出路徑')
    elif len(sys.argv) < 4:
        print('缺少加密Key')
else:
    encodeKey = sys.argv[3]
    encodeDir(sys.argv[1], sys.argv[2])
    # decodeDir(sys.argv[2], sys.argv[1])

解密

工程裏需要讀取圖片和文本時解碼,加密文件開頭拼接一個 key,這個key可以不是加密key,主要是爲了通過這個開頭來判斷,哪些是加密過的文件。
這裏主要說cocos的xcode工程

json文件以及文本文件

讀取方法在CCFileUtils.cpp getDataFromFile 和 getStringFromFile這兩個方法。

// 解密
size_t FileUtils::mydecode(const unsigned char* data, ssize_t dataLen, unsigned char ** outBuffer)
{
    static const char* encodeKey = Director::getInstance()->getBingooImg();
    
    long stringL = strlen(encodeKey);
    if(stringL <= 0 || dataLen<=stringL || memcmp(data, encodeKey, stringL) != 0)  //是否加密的標記
    {
        return dataLen;
    }
    ssize_t len = dataLen-stringL;
    *outBuffer = (unsigned char*)malloc(len);
    int key = encodeKey[stringL-1];
    for(ssize_t i=0; i<len; i++)
    {
        key = encodeKey[(i+stringL)%stringL];
        (*outBuffer)[i] = data[i+stringL] ^ key;  //最簡單的xor, 自己改算法
    }
    return len;
}

// 修改的方法1
std::string FileUtils::getStringFromFile(const std::string& filename)
{
    std::string s;
    getContents(filename, &s);
    
    Data data;
    data.copy(static_cast<unsigned char*>( static_cast<void*>( const_cast<char*>(s.data()))), s.size());
    unsigned char* decodeData = nullptr;
    size_t dsize = mydecode(data.getBytes(), data.getSize(), &decodeData);
    if (decodeData) {
        s = static_cast<char*>( static_cast<void*>( const_cast<unsigned char*>(decodeData)));
        if (s.size() > dsize) {
            std::string subs = s.substr(0, dsize);
            s = subs;
        }
    }
    return s;
}

// 修改的方法2
Data FileUtils::getDataFromFile(const std::string& filename)
{
    Data d;
    getContents(filename, &d);
    
    unsigned char* decodeData = nullptr;
    size_t dsize = mydecode(d.getBytes(), d.getSize(), &decodeData);
    if (decodeData) {
        Data data;
        data.copy(decodeData, dsize);
        d = data;
    }
    return d;
}

圖片

圖片加載的地方,在CCImage.cpp裏 initWithImageData 方法

// 解密圖片
ssize_t Image::mydecode(const unsigned char * data, ssize_t dataLen, unsigned char ** outBuffer)
{
    static const char* encodeKey = Director::getInstance()->getBingooImg();
    
    long stringL = strlen(encodeKey);
    if(stringL <= 0 || dataLen<=stringL || memcmp(data, encodeKey, stringL) != 0)  //是否加密的標記
    {
        return dataLen;
    }
    ssize_t len = dataLen-stringL;
    *outBuffer = (unsigned char*)malloc(len);
    int key = encodeKey[stringL-1];
//    CCLOG("buffer key: %d", key);
    for(ssize_t i=0; i<len; i++)
    {
        key = encodeKey[(i+stringL)%stringL];
        (*outBuffer)[i] = data[i+stringL] ^ key;  //最簡單的xor, 自己改算法
    }
    return len;
}

bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
{
    bool ret = false;

    do
    {
        CC_BREAK_IF(! data || dataLen <= 0);
        
        unsigned char* decodeData = nullptr;
        unsigned char* unpackedData = nullptr;
        ssize_t unpackedLen = 0;
		
		// 解密圖片
        dataLen = mydecode(data, dataLen, &decodeData);
//        CCLOG("buffer decodeData: %s", decodeData);
        if(decodeData)
        {
            data = decodeData;
        }
//......  後面代碼無需修改,所以省略
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章