我是靠谱客的博主 俊秀滑板,最近开发中收集的这篇文章主要介绍【步兵 经验篇】图片加密之我见【步兵 经验篇】图片加密之我见 by EOS.,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【步兵 经验篇】图片加密之我见 by EOS.

现在apk满大街飞,直接下载一个apk改后缀名为rar,就可以看到里面的东西,我相信大家都知道,
也就是说,如果资源不加密的话,游戏的美术资源就成了别人的换皮对象=。=
现在淘宝上5块钱一堆资源,美术大大们,如果看到自己的资源被当烂白菜,不知道什么心态。

不过就算加密了,也有人去研究解密,对解密这块我也不是太懂,感觉这是一个门高深的技术=。=
下面我就来说一个我用过的一个比较简单的图片加密方法。

PNG加密

先说一下思路:
首先要了解png二进制的前8位是PNG的文件标识,那么我破坏这个文件图片标识,
它就算被的加密了,最起码你用图片查看工具识别不出来了。
(比如png改成开封菜~)

从最简单的出发的,想到的可能就是改值或者换位,而我的加密就是基于这两点。
(ps:完全没用加密算法,不行了,感觉自己好low)

const char pngStart[16] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 };//89 50 4E 47 0D 0A 1A 0A 00 00 00 00 49 48 44 52
const char pngEnd[12] = { 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 };//00 00 00 00 49 45 4E 44 AE 42 60 82

//每一位都可以是 0x00~0xff,这里用字符串偷懒了=。=
char pngStartChange[16] = "what~the#fuck!e";//[15] = s
char pngEndChange[12] = "oh@my%god`e";//[11] = s

png二进制流的前16位和后12位是固定的,我们把它全部干掉,然后再打乱顺序。
因为替换字符串的可以是任意的,而且又有将近30位的排列组合,我感觉加密的可行性还是很高的。
(ps:求打脸 =3= ,因为不太懂解密。)

int index = 2;
for (int i = 0; i < 16; i++)
{
    if (i % 2 == 0)
    {
        ++index;
        swap(buf[i], buf[size - size / index]);
    }
    else
    {
        swap(buf[i], buf[size / index]);
    }
}
for (int i = 1; i <= 12; i++)
{
    auto c = buf[size - i];
    swap(buf[size - i], buf[15 + i*2]);
}

换位方式用了两种,一种是根据size,也就是图片流的大小,另一种是固定索引。
前者感觉就是感觉变数更多一些,因为每个文件大小不一样,而且换法也很多。
后者就算简单粗暴了,不过IDHR算是比较重要的所以把它也破坏掉。

文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

经过上面的处理,我感觉我们数据流已经够复杂了,基本上已经和图片没什么关系了。
他很难知道我们篡改后的字符是什么,所以他很难换位回来。而且我们换位也是有技巧的=。=

PNG解密

解密当然就是上面的加密的逆操作,就是换回来,然后再替换回原来的png头和尾部。

是不是感觉好简单啊~ 所以这里就需要特殊的换位技巧了=。=
(ps:如果你换位的奇技淫巧!请告诉我~)

而且我们操作很简单,所以解密效率自然是杠杠的。

源码

下面是我测试用的demo源码,仅供参考。

/************************************************************************/
/* 文件名称: main.cpp                                                   */
/* 简要描述:图片加密解密Demo                                           */
/*                                                                      */
/* 创建日期:忘球了                                                     */
/*                                                                      */
/* 作者:EOS.                                                           */
/************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;

const char pngStart[16] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 };//89 50 4E 47 0D 0A 1A 0A 00 00 00 00 49 48 44 52
const char pngEnd[12] = { 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 };//00 00 00 00 49 45 4E 44 AE 42 60 82

char pngStartChange[16] = "what~the#fuck!e";
char pngEndChange[12] = "oh@my%god`e";

class PNGTransform
{
public:
    PNGTransform(fpos_t s):size(s) {
        buf = new char[size];
    };
    ~PNGTransform() {
        delete[] buf;
    };
    //神一样的解说:构造析构防测漏

    void transform() {
        for (int i = 0; i < 16; i++)
        {
            buf[i] = pngStartChange[i];
        }
        for (int i = 1; i <= 12; i++)
        {
            buf[size - i] = pngEndChange[12-i];
        }

        int index = 2;
        for (int i = 0; i < 16; i++)
        {
            if (i % 2 == 0)
            {
                ++index;
                swap(buf[i], buf[size - size / index]);
            }
            else
            {
                swap(buf[i], buf[size / index]);
            }
        }
        for (int i = 1; i <= 12; i++)
        {
            auto c = buf[size - i];
            swap(buf[size - i], buf[15 + i*2]);
        }

        ofstream fout;
        fout.open("./mLS07.png", ios::binary);
        fout.write(buf, size);
        fout.close();
    };

public:
    char* buf;
    fpos_t size;
};


class PNGRestore
{
public:
    PNGRestore(fpos_t s) :size(s) {
        buf = new char[size];
    };
    ~PNGRestore() {
        delete[] buf;
    };
    void restore() {
        for (int i = 1; i <= 12; i++)
        {
            swap(buf[size - i], buf[15 + i * 2]);
        }

        //逆序防止 123 213 231 -》 231 321 321 的情况
        int index = 11;
        for (int i = 15; i >= 0; i--)
        {
            if (i % 2 == 0)
            {
                swap(buf[i], buf[size - size / index]);
            }
            else
            {
                index--;
                swap(buf[i], buf[size / index]);
            }
        }

        for (int i = 0; i < 16; i++)
        {
            buf[i] = pngStart[i];
        }
        for (int i = 1; i <= 12; i++)
        {
            buf[size - i] = pngEnd[12 - i];
        }

        ofstream fout;
        fout.open("./rLS07.png", ios::binary);
        fout.write(buf, size);
        fout.close();
    };

public:
    char* buf;
    fpos_t size;
};

template<class T>
fpos_t GetFileSize(T& fs)
{
    fs.seekg(0, ios::end);
    auto fileSize = fs.tellg().seekpos();
    fs.seekg(0);
    return fileSize;
}

int main()
{
    pngStartChange[15] = pngEndChange[11] = 's';
#define PNGTRANSFORM  0
#define PNGBUFCHECK 0

#if PNGTRANSFORM == 1
    ifstream fin;
    fin.open("LS07.png", ios::binary);
    auto fileSize = GetFileSize(fin);

    PNGTransform trans(fileSize);
    fin.read(trans.buf, fileSize);
    fin.close();

    trans.transform();
#else
    ifstream fin;
    fin.open("mLS07.png", ios::binary);
    auto fileSize = GetFileSize(fin);

    PNGRestore reset(fileSize);
    fin.read(reset.buf, fileSize);
    fin.close();

    reset.restore();
#endif

#if PNGBUFCHECK
    ifstream fin;
    fin.open("LS07.png", ios::binary);
    auto fileSize = GetFileSize(fin);

    PNGTransform trans(fileSize);
    fin.read(trans.buf, fileSize);
    fin.close();


    fin.open("rLS07.png", ios::binary);
    fileSize = GetFileSize(fin);

    PNGRestore reset(fileSize);
    fin.read(reset.buf, fileSize);
    fin.close();
    reset.restore();

    fpos_t xx = 0;
    while (xx < reset.size)
    {
        if (reset.buf[xx] != trans.buf[xx])
        {
            break;
        }
        xx++;
    }
#endif

    system("pause");
    return 0;
}

如果觉得此可行,请参考代码自行修改。

See Again~
之前
真爱无价,欢迎打赏~
赞赏码

最后

以上就是俊秀滑板为你收集整理的【步兵 经验篇】图片加密之我见【步兵 经验篇】图片加密之我见 by EOS.的全部内容,希望文章能够帮你解决【步兵 经验篇】图片加密之我见【步兵 经验篇】图片加密之我见 by EOS.所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(64)

评论列表共有 0 条评论

立即
投稿
返回
顶部