123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public class SecretEncoder : MonoBehaviour {
- public static int Decode(string data)
- {
- int result = 0;
- //восстанавливаем сартовый индекс значения
- int scoreStart = data.IndexOf(data[34])*10 + data.IndexOf(data[35]);
- //восстанавливаем длину значения
- int scoreLen = data.IndexOf(data[36]);
- //получаем зашифрованный результат
- var resultEnc = data.Substring(scoreStart, scoreLen).ToCharArray();
- //расшифровываем
- for (int i = 0; i < resultEnc.Length; i++)
- {
- resultEnc[i] = data.IndexOf(resultEnc[i]).ToString()[0];
- }
- //превращаем в число
- result = int.Parse(new string(resultEnc));
- //отнимаем 786 т.к. при упаковке мы его добавляли
- result -= 786;
- //и делим на два, т.к. при упаковке умножали
- result /= 2;
- return result;
- }
- public static string Encode(int score)
- {
- // ограничим очки, рельными пределами, т.к. они не могут быть меньше чем 0 и больше половины милиарда
- // т.к. для получения такого результата придется бежать более 15 лет не останавливаясь.
- score = Mathf.Clamp(score, 0, 400000000);
- //увеличим число на два
- score *= 2;
- //прибавим 786, для пущей запутанности
- score += 786;
-
- // все доступные символы
- const string allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- // в этой строке будет хранится результат
- char[] resut = new char[100];
- // заполняем строку мусором
- for (int i = 0; i < 100; i++)
- {
- resut[i] = allowed[Random.Range(0, allowed.Length)];
- }
- // создаем секвенцию для ассоциации букв-символов
- var sequence = new List<char>(allowed);
- // отсортируем в случайном порядке
- sequence.Sort((c, c1) => { return UnityEngine.Random.Range(-1, 2); });
- // перенесем первых 10 символов в результирующую строку
- for (int i = 0; i < 10; i++)
- {
- resut[i] = sequence[i];
- }
- // выберем случайное место, где будет хранится значения очков
- var scoreIndex = Random.Range(40, 90);
- // закодируем нашей секвенцией
- var scoreIndexEnc = EncodeIntBySecret(resut, scoreIndex);
- // закодируем нашей секвенцией очки
- var scoreEnc = EncodeIntBySecret(resut, score);
- // для успешной дешифрации, нам нужно знать какой длины scoreEnc (сколько символов оно занимает)
- var scoreLenEnc = EncodeIntBySecret(resut, scoreEnc.Length);
- // сохраним наши данные в результат
- // сначала запишем scoreIndexEnc в 34 и 35 индекс
- // тут всегда будет два символа, т.к. допустимый диапазон от 40 до 90 всегда будет состоять из двух чисел
- resut[34] = scoreIndexEnc[0];
- resut[35] = scoreIndexEnc[1];
- //запишем количество символов в очках в 36 индекс, сразу после scoreIndexEncs
- resut[36] = scoreLenEnc[0];
- //запишем сами очки в результирующий массив
- for (int i = 0; i < scoreEnc.Length; i++)
- {
- resut[i + scoreIndex] = scoreEnc[i];
- }
- return new string(resut);
- }
- //шифрация числа при помощи секрета
- private static char[] EncodeIntBySecret(char[] serctet, int value)
- {
- // приобразуем значение в строку
- var data = value.ToString();
- //тут будет хранится результат шифрования
- char[] result = new char[data.Length];
- for (int i = 0; i < data.Length; i++)
- {
- //преобразуем число в букву по индексу секрета
- result[i] = serctet[int.Parse("" + data[i])];
- }
- return result;
- }
- }
|