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.2 kB

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