Unity 游戏数据的存档读档,数据加密与解密

untiy中单机游戏的读档与存档有4方式,一种是unity自带的数据持久化方案PlayerPrefs 采用键值对的方式, 可以存储Int,Float,String类型的数据。

一般复杂和大量的数据通过序列化(Serialize)来保存数据

常见的3种:二进制,XML方法,Json方法 

二进制方法:简单,但可读性差  

XML方法:可读性强,但是文件庞大,冗余信息多

JSON方法:数据格式比较简单,易于读写,但是不直观,可读性比XML差

这里介绍JSON(LitJson)方法:

using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace ArrowLegend
{
    /// 
    /// 存档读档组件
    /// 
    public class SaveComponent :GameFrameworkComponent
    {
        private string key = "123456789";
        /// 
        /// 测试存档
        /// 
        /// 
        private SaveData CreateSaveData()
        {
            SaveData saveData = new SaveData();
            //TODO 保存游戏对象
            saveData.currentLevel = 10;
            return saveData;
        }
        /// 
        /// 测试读档
        /// 
        /// 
        private void SetGame(SaveData saveData)
        {
            Debug.LogFormat("当前关卡:{0}", saveData.currentLevel);
        }
        private void SaveByJson()
        {
            SaveData saveData = CreateSaveData();
            string filePath = Application.dataPath + "/Resources" + "/byJson.json";
            string saveJsonStr = JsonMapper.ToJson(saveData);
            
            StreamWriter sw = new StreamWriter(filePath);
            sw.Write(EncryptionTool.EncryptString( saveJsonStr,key));
            sw.Close();
            Debug.Log("保存成功");
        }
        private void LoadByJson()
        {
            string filePath = Application.dataPath + "/Resources" + "/byJson.json";
            if (File.Exists(filePath))
            {
                StreamReader sr = new StreamReader(filePath);
                string jsonStr = sr.ReadToEnd();
                jsonStr = EncryptionTool.DecryptString(jsonStr, key);
                sr.Close();
                SaveData saveData = JsonMapper.ToObject(jsonStr);
                SetGame(saveData);
            }
        }
        /// 
        /// 保存游戏
        /// 
        public void SaveGame()
        {
            SaveByJson();
        }
        /// 
        /// 加载游戏
        /// 
        public void LoadGame()
        {
            LoadByJson();
        }
    }
}

其中使用了一个加密解密工具,这个工具可以加密json文件,防止恶意篡改。

using System;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
namespace ArrowLegend
{
    /// 
    /// 加密和解密工具类
    /// 
    public class EncryptionTool
    {
        /// 
        /// 加密算法
        /// 
        /// 要加密的字符串
        /// 加密钥匙
        /// 
        public static string EncryptString(string str,string key)
        {
            byte[] buffer;
            UTF8Encoding encoding = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] buffer2 = provider.ComputeHash(encoding.GetBytes(key));
            TripleDESCryptoServiceProvider provider2 = new TripleDESCryptoServiceProvider
            {
                Key = buffer2,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };
            byte[] bytes = encoding.GetBytes(str);
            try
            {
                buffer =  provider2.CreateEncryptor().TransformFinalBlock(bytes,0,bytes.Length);
            }
            finally
            {
                provider2.Clear();
                provider.Clear();
            }
            return Convert.ToBase64String(buffer);
        }
        /// 
        /// 解密
        /// 
        /// 
        /// 
        /// 
        public static string DecryptString(string str,string key)
        {
            byte[] buffer;
            UTF8Encoding encoding = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] buffer2 = provider.ComputeHash(encoding.GetBytes(key));
            TripleDESCryptoServiceProvider provider2 = new TripleDESCryptoServiceProvider
            {
                Key = buffer2,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };
            try
            {
                byte[] inputBuffer = Convert.FromBase64String(str);
                buffer = provider2.CreateDecryptor().TransformFinalBlock(inputBuffer,0 ,  inputBuffer.Length);
            }
            catch (Exception ex)
            {
                Debug.LogError("DecryptString failed. return empty string." + ex.Message);
                return "";
            }
            finally
            {
                provider2.Clear();
                provider.Clear();
            }
            return encoding.GetString(buffer);
        }
    }
}

 

你可能感兴趣的:(项目笔记)