• 热门专题

Unity3d游戏资源打包加密(图片/XML/TXT等)C#编码(一)

作者:  发布日期:2015-01-25 21:33:55
Tag标签:游戏资源  编码  图片  
  • 本文只是讲述一下过程,采用很简单的打包加密方法,至于需要什么样的加密结果,请大家按照需求去修改,字节偏移、前后颠倒加算法都可以,不过一般无需这么复杂,而且太复杂的加密对于极其追求运行效率的游戏来说,也是一重负担。

    对于Unity,虽然Unity自身会进行压缩加密,但是其解密算法在网上随处可见,如果自己觉得游戏里面的资料具有保密性质,请对其进行自行加密。

    打包加密的原理:

    1、大家都知道文件都是由字节组成的。

    2、一张图片之所以看起来很漂亮,是因为其数据按照一定顺序排列。

    漂亮的剑灵妹子

    我们可以用一个文本编辑器将其打开。

    是乱码,不然你还想看到什么呢?

    3、如果我们把图片数据打乱,或者在前面加一些很乱的数据,会怎么样呢?

    嗯,图片不显示了。

    这很容易理解,就像你看片的时候被打了马赛克嘛。。

    仔细想想,为什么打马赛克?

    不就是为了保密嘛。。。

    好的,上面我们就起到了保密-加密功能。

    4、我又找来一张图片……萌萌哒的。。

    同样用一个文本编辑器打开这个图片。

    复制所有的内容到第一个图片文件后面。

    结果会怎么样?

    两个图片会拼在一起吗?

    真不幸……

    不过这是符合我的主题的。加密嘛,就是要让人看不出来。

    原理就讲到这里,下面就是代码了。

    代码不是针对单个文件,而是对多个文件夹进行打包加密。

    加密方法仅仅是多个文件打包。

    -----------------------------------------------------------------------------------

    我是可爱的分割线

    -----------------------------------------------------------------------------------

    用到的知识点:

    1、读写文件

    2、对文件夹、文件的操作,获取所有的文件

     

    -----------------------------------------------------------------------------------

    我是可爱的分割线

    -----------------------------------------------------------------------------------

    下面是主要的代码:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    
    namespace MyPackRes
    {
        class Helper
        {
            public static void Log(string str)
            {
                Console.Write(str+"
    
    ");
            }
    
            public static void Pause()
            {
                Console.Write("Press any key to continue . . . ");
                Console.ReadKey(true);
            }
        }
    }
    

     

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    using System.Diagnostics;
    
    namespace MyPackRes
    {
        class Program
        {
            private static int m_id=0;
            private static int m_totalSize = 0;
    
    //         private static List<int> m_idList = new List<int>();
    //         private static List<int> m_startPosList = new List<int>();
    //         private static List<int> m_sizeList = new List<int>();
    //         private static List<string> m_pathList = new List<string>();
    
            private static Dictionary<int,OneFileInfor> m_allFileInfoDic = new Dictionary<int,OneFileInfor>();
    
            private static string m_currentDir = "";
    
            static void Main(string[] args)
            {
                m_currentDir = Environment.CurrentDirectory;
    
                Helper.Log("MyPackRes Start " + m_currentDir);
    
                List<string> folderToPackList = new List<string>();
    
                /**  读取配置文件  **/
                Helper.Log("需要打包的文件夹:");
                StreamReader streamReader = new StreamReader("MyPackRes.ini", Encoding.Default);
                string line;
                while ((line=streamReader.ReadLine())!=null)
                {
                    Helper.Log(line);
                    if (!folderToPackList.Contains(line))
                    {
                        folderToPackList.Add(line);
                    }
                }
                streamReader.Close();
    
                /**  遍历打包文件夹 **/
                for (int index = 0; index < folderToPackList.Count;index++ )
                {
                    PackFolder(folderToPackList[index]);
                }
    
                Helper.Log("打包完毕!");
                Helper.Pause();
            }
    
            /** 遍历文件夹获取所有文件信息 **/
            private static void TraverseFolder(string foldername)
            {
                Helper.Log("遍历文件夹 " + foldername);
    
                /** 读取文件夹下面所有文件的信息 **/
                DirectoryInfo dirInfo = new DirectoryInfo(foldername);
    
                foreach (FileInfo fileinfo in dirInfo.GetFiles("*.*",SearchOption.AllDirectories))
                {
                    string filename = (fileinfo.FullName.Replace(m_currentDir+"\","")).Replace("\","/");
                    int filesize = (int)fileinfo.Length;
    
                    Helper.Log(m_id + " : " + filename + " 文件大小: " + filesize);
    
                    OneFileInfor info = new OneFileInfor();
                    info.m_id = m_id;
                    info.m_Size = filesize;
                    info.m_Path = filename;
                    
                    /**  读取这个文件  **/
                    FileStream fileStreamRead = new FileStream(fileinfo.FullName, FileMode.Open, FileAccess.Read);
                    if (fileStreamRead == null)
                    {
                        Helper.Log("读取文件失败 : "+fileinfo.FullName);
                        Helper.Pause();
                        return;
                    }
                    else
                    {
                        byte[] filedata = new byte[filesize];
                        fileStreamRead.Read(filedata, 0, filesize);
                        info.m_data = filedata;
                    }
                    fileStreamRead.Close();
    
    
                    m_allFileInfoDic.Add(m_id,info);
    
                    m_id++;
                    m_totalSize += filesize;
                }
            }
    
    
            /**  打包一个文件夹  **/
            private static void PackFolder(string foldername)
            {
                TraverseFolder(foldername);
    
                Helper.Log("文件数量 : " + m_id);
                Helper.Log("文件总大小 : " + m_totalSize);
    
                /**  更新文件在UPK中的起始点  **/
                int firstfilestartpos = 4 + (4 + 4 + 4 + 256) * m_allFileInfoDic.Count;
                int startpos = 0;
                for (int index = 0; index < m_allFileInfoDic.Count; index++)
                {
                    if (index == 0)
                    {
                        startpos = firstfilestartpos;
                    }
                    else
                    {
                        startpos = m_allFileInfoDic[index - 1].m_StartPos + m_allFileInfoDic[index - 1].m_Size;//上一个文件的开始+文件大小;
                    }
    
                    m_allFileInfoDic[index].m_StartPos = startpos;
                }
    
                /**  写文件  **/
                FileStream fileStream = new FileStream(foldername + ".UPK", FileMode.Create);
    
                /**  文件总数量  **/
                byte[] totaliddata=System.BitConverter.GetBytes(m_id);
                fileStream.Write(totaliddata, 0, totaliddata.Length);
    
                for (int index = 0; index < m_allFileInfoDic.Count;index++ )
                {
                    /** 写入ID **/
                    byte[] iddata = System.BitConverter.GetBytes(m_allFileInfoDic[index].m_id);
                    fileStream.Write(iddata, 0, iddata.Length);
    
                    /**  写入StartPos  **/
                    byte[] startposdata = System.BitConverter.GetBytes(m_allFileInfoDic[index].m_StartPos);
                    fileStream.Write(startposdata, 0, startposdata.Length);
    
                    /**  写入size  **/
                    byte[] sizedata = System.BitConverter.GetBytes(m_allFileInfoDic[index].m_Size);
                    fileStream.Write(sizedata, 0, sizedata.Length);
    
                    /**  写入path  **/
                    byte[] pathdata = new byte[256];
                    byte[] mypathdata = new UTF8Encoding().GetBytes(m_allFileInfoDic[index].m_Path);
    
                    for (int i = 0; i < mypathdata.Length; i++)
                    {
                        pathdata[i] = mypathdata[i];
                    }
                    pathdata[mypathdata.Length] = 0;
    
                    fileStream.Write(pathdata, 0, pathdata.Length);                
                }
    
                /**  写入文件数据  **/
                for (int index = 0; index < m_allFileInfoDic.Count; index++)
                {
                    fileStream.Write(m_allFileInfoDic[index].m_data, 0, m_allFileInfoDic[index].m_Size);
                }
    
                fileStream.Flush();
                fileStream.Close();
    
    
                /** 重置数据 **/
                m_id = 0;
                m_totalSize = 0;
                m_allFileInfoDic.Clear();
    
            }
        }
    
    
        public class OneFileInfor
        {
            public int m_id=0;
            public int m_StartPos=0;
            public int m_Size=0;
            public string m_Path="";
            public byte[] m_data = null;
        };
    }
    

     

    -----------------------------------------------------------------------------------

    我是可爱的分割线

    -----------------------------------------------------------------------------------

    代码浅显易懂 ( # ▽ # )

    首先新建一个配置文件

    MyPackRes.ini

    里面添加需要打包的文件夹 每行一个:

    看看我们运行结果。

    首先看看我准备的图。从碧之轨迹中TP抽取的哦。

    打包结束后,会生成UPK文件。

    UPK,这个后缀是虚幻引擎的默认资源文件格式哦。

    最后附上工程:

    http://www.it165.net/uploadfile/files/2015/0125/MyPackRes.zip

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规