Xxtea.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**********************************************************\
  2. | |
  3. | XXTEA.cs |
  4. | |
  5. | XXTEA encryption algorithm library for .NET. |
  6. | |
  7. | Encryption Algorithm Authors: |
  8. | David J. Wheeler |
  9. | Roger M. Needham |
  10. | |
  11. | Code Author: Ma Bingyao <mabingyao@gmail.com> |
  12. | LastModified: Mar 10, 2015 |
  13. | |
  14. \**********************************************************/
  15. namespace Security {
  16. using System;
  17. using System.Text;
  18. public sealed class XXTEA {
  19. private static readonly UTF8Encoding utf8 = new UTF8Encoding();
  20. private const UInt32 delta = 0x9E3779B9;
  21. private static UInt32 MX(UInt32 sum, UInt32 y, UInt32 z, Int32 p, UInt32 e, UInt32[] k) {
  22. return (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
  23. }
  24. private XXTEA() {
  25. }
  26. public static Byte[] Encrypt(Byte[] data, Byte[] key) {
  27. if (data.Length == 0) {
  28. return data;
  29. }
  30. return ToByteArray(Encrypt(ToUInt32Array(data, true), ToUInt32Array(FixKey(key), false)), false);
  31. }
  32. public static Byte[] Encrypt(String data, Byte[] key) {
  33. return Encrypt(utf8.GetBytes(data), key);
  34. }
  35. public static Byte[] Encrypt(Byte[] data, String key) {
  36. return Encrypt(data, utf8.GetBytes(key));
  37. }
  38. public static Byte[] Encrypt(String data, String key) {
  39. return Encrypt(utf8.GetBytes(data), utf8.GetBytes(key));
  40. }
  41. public static String EncryptToBase64String(Byte[] data, Byte[] key) {
  42. return Convert.ToBase64String(Encrypt(data, key));
  43. }
  44. public static String EncryptToBase64String(String data, Byte[] key) {
  45. return Convert.ToBase64String(Encrypt(data, key));
  46. }
  47. public static String EncryptToBase64String(Byte[] data, String key) {
  48. return Convert.ToBase64String(Encrypt(data, key));
  49. }
  50. public static String EncryptToBase64String(String data, String key) {
  51. return Convert.ToBase64String(Encrypt(data, key));
  52. }
  53. public static Byte[] Decrypt(Byte[] data, Byte[] key) {
  54. if (data.Length == 0) {
  55. return data;
  56. }
  57. return ToByteArray(Decrypt(ToUInt32Array(data, false), ToUInt32Array(FixKey(key), false)), true);
  58. }
  59. public static Byte[] Decrypt(Byte[] data, String key) {
  60. return Decrypt(data, utf8.GetBytes(key));
  61. }
  62. public static Byte[] DecryptBase64String(String data, Byte[] key) {
  63. return Decrypt(Convert.FromBase64String(data), key);
  64. }
  65. public static Byte[] DecryptBase64String(String data, String key) {
  66. return Decrypt(Convert.FromBase64String(data), key);
  67. }
  68. public static String DecryptToString(Byte[] data, Byte[] key) {
  69. return utf8.GetString(Decrypt(data, key));
  70. }
  71. public static String DecryptToString(Byte[] data, String key) {
  72. return utf8.GetString(Decrypt(data, key));
  73. }
  74. public static String DecryptBase64StringToString(String data, Byte[] key) {
  75. return utf8.GetString(DecryptBase64String(data, key));
  76. }
  77. public static String DecryptBase64StringToString(String data, String key) {
  78. return utf8.GetString(DecryptBase64String(data, key));
  79. }
  80. private static UInt32[] Encrypt(UInt32[] v, UInt32[] k) {
  81. Int32 n = v.Length - 1;
  82. if (n < 1) {
  83. return v;
  84. }
  85. UInt32 z = v[n], y, sum = 0, e;
  86. Int32 p, q = 6 + 52 / (n + 1);
  87. unchecked {
  88. while (0 < q--) {
  89. sum += delta;
  90. e = sum >> 2 & 3;
  91. for (p = 0; p < n; p++) {
  92. y = v[p + 1];
  93. z = v[p] += MX(sum, y, z, p, e, k);
  94. }
  95. y = v[0];
  96. z = v[n] += MX(sum, y, z, p, e, k);
  97. }
  98. }
  99. return v;
  100. }
  101. private static UInt32[] Decrypt(UInt32[] v, UInt32[] k) {
  102. Int32 n = v.Length - 1;
  103. if (n < 1) {
  104. return v;
  105. }
  106. UInt32 z, y = v[0], sum, e;
  107. Int32 p, q = 6 + 52 / (n + 1);
  108. unchecked {
  109. sum = (UInt32)(q * delta);
  110. while (sum != 0) {
  111. e = sum >> 2 & 3;
  112. for (p = n; p > 0; p--) {
  113. z = v[p - 1];
  114. y = v[p] -= MX(sum, y, z, p, e, k);
  115. }
  116. z = v[n];
  117. y = v[0] -= MX(sum, y, z, p, e, k);
  118. sum -= delta;
  119. }
  120. }
  121. return v;
  122. }
  123. private static Byte[] FixKey(Byte[] key) {
  124. if (key.Length == 16) return key;
  125. Byte[] fixedkey = new Byte[16];
  126. if (key.Length < 16) {
  127. key.CopyTo(fixedkey, 0);
  128. }
  129. else {
  130. Array.Copy(key, 0, fixedkey, 0, 16);
  131. }
  132. return fixedkey;
  133. }
  134. private static UInt32[] ToUInt32Array(Byte[] data, Boolean includeLength) {
  135. Int32 length = data.Length;
  136. Int32 n = (((length & 3) == 0) ? (length >> 2) : ((length >> 2) + 1));
  137. UInt32[] result;
  138. if (includeLength) {
  139. result = new UInt32[n + 1];
  140. result[n] = (UInt32)length;
  141. }
  142. else {
  143. result = new UInt32[n];
  144. }
  145. for (Int32 i = 0; i < length; i++) {
  146. result[i >> 2] |= (UInt32)data[i] << ((i & 3) << 3);
  147. }
  148. return result;
  149. }
  150. private static Byte[] ToByteArray(UInt32[] data, Boolean includeLength) {
  151. Int32 n = data.Length << 2;
  152. if (includeLength) {
  153. Int32 m = (Int32)data[data.Length - 1];
  154. n -= 4;
  155. if ((m < n - 3) || (m > n)) {
  156. return null;
  157. }
  158. n = m;
  159. }
  160. Byte[] result = new Byte[n];
  161. for (Int32 i = 0; i < n; i++) {
  162. result[i] = (Byte)(data[i >> 2] >> ((i & 3) << 3));
  163. }
  164. return result;
  165. }
  166. }
  167. }