大佬们复杂的加密我看不懂┭┮﹏┭┮。
我自己对游戏存档加密的理解,仅仅是让玩家打开游戏存档txt或者json文件的时候,显示一堆乱码而已。
我自己简单实现了一个游戏本地数据加密(我也不知道这样有没有用),思路是:
1.将游戏数据都存放在字典或者集合里,然后使用unity自带的JsonUtility.ToJson()方法,获取序列化的字符串(str1)。
2.将获取到的字符串(str1)转换成字节数组byte[](假设名字为byte1),将该数组的每一个字节都右移>>2(这个过程可以更复杂一些)。
3.将简单处理过的字节数组(byte1)直接写入text.json或者text.txt文件(后缀名应该可以改得更不同寻常一点,反正别让玩家认出这是个存档文件就好)
4.读取数据,将文件读到新的byte[](假设名字为byte2),将该数组的每一个字节都左移<<2
5.反序列化JsonUtility.FromJson(),结束
代码如下:
private void Awake()
{
//先随便建一个字典
Dictionary<int, string> di = new Dictionary<int, string>();
di.Add(1, "hello你好");
//序列化该字典,s的值为{"keys":[1],"values":["hello你好"]},SerializeDictionary这个类的实现在文章最后
string s=SerializeDictionary.DicToJson<int,string>(di);
//原始字节数据(originalData)
byte[] oriData =System.Text.Encoding.Default.GetBytes(s);
//修改之后要存放的乱码数据(resultData)
byte[] resData=new byte[oriData.Length+1];
//最后一个自己随便设个值,不过前两位要为00
resData[oriData.Length] = 0b00010100;
for (int i = oriData.Length - 1; i >= 0; --i)
{
resData[i] = (byte)(oriData[i] >> 2);
resData[i + 1] = (byte)(((oriData[i] & (0b00000011)) << 6) | resData[i+1]);
}
//将乱码文件写入test2.json中
FileStream f= File.Open(Application.dataPath + "\\Json\\test2.json",FileMode.OpenOrCreate);
f.Write(resData, 0, resData.Length);
f.Close();
//读取test2.json的文件
byte[] resData2 = File.ReadAllBytes(Application.dataPath + "\\Json\\test2.json");
byte[] oriData2=new byte[resData2.Length-1];
for (int i = 0; i < oriData.Length; i++)
{
oriData2[i]= (byte)((resData2[i] << 2) | ((resData2[i+1]&0b11000000)>>6));
}
//查看结果
string s2=System.Text.Encoding.Default.GetString(oriData2);
print(s2);
}
处理方式是把每个字节向后移动两位
没有移位的文本本来是这样的:
移位后的文本是这样的:
读取乱码文本的结果也是正确的:
关于Dictionary的序列化,unity自带的是不行的,结果为{}。也无法直接的对List<T>对象进行序列化和反序列化,需要将List<T>包装(Wrap)到一个类当中,然后序列化和反序列化包含这个List<T>的对象即可。
序列化dictionary的方法是用两个list分别代表key和value,然后序列化两个list。
代码如下(找不到那篇文章了):
public class SerializeDictionary
{
public static string DicToJson<TKey, TValue>(Dictionary<TKey, TValue> dic)
{
return JsonUtility.ToJson(new SerializeDictionary<TKey, TValue>(dic));
}
public static Dictionary<TKey, TValue> DicFromJson<TKey, TValue>(string str)
{
return JsonUtility.FromJson<SerializeDictionary<TKey, TValue>>(str).ToDictionary();
}
}
[Serializable]
public class SerializeDictionary<TKey, TValue> : ISerializationCallbackReceiver
{
[SerializeField]
List<TKey> keys;
[SerializeField]
List<TValue> values;
Dictionary<TKey, TValue> target;
public Dictionary<TKey, TValue> ToDictionary() { return target; }
public SerializeDictionary(Dictionary<TKey, TValue> target)
{
this.target = target;
}
public void OnBeforeSerialize()
{
keys = new List<TKey>(target.Keys);
values = new List<TValue>(target.Values);
}
public void OnAfterDeserialize()
{
var count = Math.Min(keys.Count, values.Count);
target = new Dictionary<TKey, TValue>(count);
for (var i = 0; i < count; ++i)
{
target.Add(keys[i], values[i]);
}
}
}