You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

TableEncryptor.cs 3.4 kB

10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Shadowsocks.Encryption
  4. {
  5. public class TableEncryptor
  6. : EncryptorBase
  7. {
  8. public TableEncryptor(string method, string password, bool onetimeauth, bool isudp)
  9. : base(method, password, onetimeauth, isudp)
  10. {
  11. byte[] hash = GetPasswordHash();
  12. // TODO endian
  13. ulong a = BitConverter.ToUInt64(hash, 0);
  14. for (int i = 0; i < 256; i++)
  15. {
  16. _encryptTable[i] = (byte)i;
  17. }
  18. for (int i = 1; i < 1024; i++)
  19. {
  20. _encryptTable = MergeSort(_encryptTable, a, i);
  21. }
  22. for (int i = 0; i < 256; i++)
  23. {
  24. _decryptTable[_encryptTable[i]] = (byte)i;
  25. }
  26. }
  27. public static List<string> SupportedCiphers()
  28. {
  29. return new List<string>(new string[]{"table"});
  30. }
  31. public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
  32. {
  33. byte[] result = new byte[length];
  34. for (int i = 0; i < length; i++)
  35. {
  36. outbuf[i] = _encryptTable[buf[i]];
  37. }
  38. outlength = length;
  39. }
  40. public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
  41. {
  42. byte[] result = new byte[length];
  43. for (int i = 0; i < length; i++)
  44. {
  45. outbuf[i] = _decryptTable[buf[i]];
  46. }
  47. outlength = length;
  48. }
  49. private readonly byte[] _encryptTable = new byte[256];
  50. private readonly byte[] _decryptTable = new byte[256];
  51. private static long Compare(byte x, byte y, ulong a, int i)
  52. {
  53. return (long)(a % (ulong)(x + i)) - (long)(a % (ulong)(y + i));
  54. }
  55. private byte[] MergeSort(byte[] array, ulong a, int j)
  56. {
  57. if (array.Length == 1)
  58. {
  59. return array;
  60. }
  61. int middle = array.Length / 2;
  62. byte[] left = new byte[middle];
  63. for (int i = 0; i < middle; i++)
  64. {
  65. left[i] = array[i];
  66. }
  67. byte[] right = new byte[array.Length - middle];
  68. for (int i = 0; i < array.Length - middle; i++)
  69. {
  70. right[i] = array[i + middle];
  71. }
  72. left = MergeSort(left, a, j);
  73. right = MergeSort(right, a, j);
  74. int leftptr = 0;
  75. int rightptr = 0;
  76. byte[] sorted = new byte[array.Length];
  77. for (int k = 0; k < array.Length; k++)
  78. {
  79. if (rightptr == right.Length || ((leftptr < left.Length) && (Compare(left[leftptr], right[rightptr], a, j) <= 0)))
  80. {
  81. sorted[k] = left[leftptr];
  82. leftptr++;
  83. }
  84. else if (leftptr == left.Length || ((rightptr < right.Length) && (Compare(right[rightptr], left[leftptr], a, j)) <= 0))
  85. {
  86. sorted[k] = right[rightptr];
  87. rightptr++;
  88. }
  89. }
  90. return sorted;
  91. }
  92. public override void Dispose()
  93. {
  94. }
  95. }
  96. }