SecretEncoder.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public class SecretEncoder : MonoBehaviour {
  5. public static int Decode(string data)
  6. {
  7. int result = 0;
  8. //восстанавливаем сартовый индекс значения
  9. int scoreStart = data.IndexOf(data[34])*10 + data.IndexOf(data[35]);
  10. //восстанавливаем длину значения
  11. int scoreLen = data.IndexOf(data[36]);
  12. //получаем зашифрованный результат
  13. var resultEnc = data.Substring(scoreStart, scoreLen).ToCharArray();
  14. //расшифровываем
  15. for (int i = 0; i < resultEnc.Length; i++)
  16. {
  17. resultEnc[i] = data.IndexOf(resultEnc[i]).ToString()[0];
  18. }
  19. //превращаем в число
  20. result = int.Parse(new string(resultEnc));
  21. //отнимаем 786 т.к. при упаковке мы его добавляли
  22. result -= 786;
  23. //и делим на два, т.к. при упаковке умножали
  24. result /= 2;
  25. return result;
  26. }
  27. public static string Encode(int score)
  28. {
  29. // ограничим очки, рельными пределами, т.к. они не могут быть меньше чем 0 и больше половины милиарда
  30. // т.к. для получения такого результата придется бежать более 15 лет не останавливаясь.
  31. score = Mathf.Clamp(score, 0, 400000000);
  32. //увеличим число на два
  33. score *= 2;
  34. //прибавим 786, для пущей запутанности
  35. score += 786;
  36. // все доступные символы
  37. const string allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  38. // в этой строке будет хранится результат
  39. char[] resut = new char[100];
  40. // заполняем строку мусором
  41. for (int i = 0; i < 100; i++)
  42. {
  43. resut[i] = allowed[Random.Range(0, allowed.Length)];
  44. }
  45. // создаем секвенцию для ассоциации букв-символов
  46. var sequence = new List<char>(allowed);
  47. // отсортируем в случайном порядке
  48. sequence.Sort((c, c1) => { return UnityEngine.Random.Range(-1, 2); });
  49. // перенесем первых 10 символов в результирующую строку
  50. for (int i = 0; i < 10; i++)
  51. {
  52. resut[i] = sequence[i];
  53. }
  54. // выберем случайное место, где будет хранится значения очков
  55. var scoreIndex = Random.Range(40, 90);
  56. // закодируем нашей секвенцией
  57. var scoreIndexEnc = EncodeIntBySecret(resut, scoreIndex);
  58. // закодируем нашей секвенцией очки
  59. var scoreEnc = EncodeIntBySecret(resut, score);
  60. // для успешной дешифрации, нам нужно знать какой длины scoreEnc (сколько символов оно занимает)
  61. var scoreLenEnc = EncodeIntBySecret(resut, scoreEnc.Length);
  62. // сохраним наши данные в результат
  63. // сначала запишем scoreIndexEnc в 34 и 35 индекс
  64. // тут всегда будет два символа, т.к. допустимый диапазон от 40 до 90 всегда будет состоять из двух чисел
  65. resut[34] = scoreIndexEnc[0];
  66. resut[35] = scoreIndexEnc[1];
  67. //запишем количество символов в очках в 36 индекс, сразу после scoreIndexEncs
  68. resut[36] = scoreLenEnc[0];
  69. //запишем сами очки в результирующий массив
  70. for (int i = 0; i < scoreEnc.Length; i++)
  71. {
  72. resut[i + scoreIndex] = scoreEnc[i];
  73. }
  74. return new string(resut);
  75. }
  76. //шифрация числа при помощи секрета
  77. private static char[] EncodeIntBySecret(char[] serctet, int value)
  78. {
  79. // приобразуем значение в строку
  80. var data = value.ToString();
  81. //тут будет хранится результат шифрования
  82. char[] result = new char[data.Length];
  83. for (int i = 0; i < data.Length; i++)
  84. {
  85. //преобразуем число в букву по индексу секрета
  86. result[i] = serctet[int.Parse("" + data[i])];
  87. }
  88. return result;
  89. }
  90. }