194 lines
6.1 KiB
C#
194 lines
6.1 KiB
C#
/**********************************************************\
|
|
| |
|
|
| XXTEA.cs |
|
|
| |
|
|
| XXTEA encryption algorithm library for .NET. |
|
|
| |
|
|
| Encryption Algorithm Authors: |
|
|
| David J. Wheeler |
|
|
| Roger M. Needham |
|
|
| |
|
|
| Code Author: Ma Bingyao <mabingyao@gmail.com> |
|
|
| LastModified: Mar 10, 2015 |
|
|
| |
|
|
\**********************************************************/
|
|
|
|
|
|
using System;
|
|
using System.Text;
|
|
|
|
public sealed class XXTEA {
|
|
private static readonly UTF8Encoding utf8 = new UTF8Encoding();
|
|
|
|
private const UInt32 delta = 0x9E3779B9;
|
|
|
|
private static UInt32 MX(UInt32 sum, UInt32 y, UInt32 z, Int32 p, UInt32 e, UInt32[] k) {
|
|
return (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
|
|
}
|
|
|
|
private XXTEA() {
|
|
}
|
|
|
|
public static Byte[] Encrypt(Byte[] data, Byte[] key) {
|
|
if (data.Length == 0) {
|
|
return data;
|
|
}
|
|
return ToByteArray(Encrypt(ToUInt32Array(data, true), ToUInt32Array(FixKey(key), false)), false);
|
|
}
|
|
|
|
public static Byte[] Encrypt(String data, Byte[] key) {
|
|
return Encrypt(utf8.GetBytes(data), key);
|
|
}
|
|
|
|
public static Byte[] Encrypt(Byte[] data, String key) {
|
|
return Encrypt(data, utf8.GetBytes(key));
|
|
}
|
|
|
|
public static Byte[] Encrypt(String data, String key) {
|
|
return Encrypt(utf8.GetBytes(data), utf8.GetBytes(key));
|
|
}
|
|
|
|
public static String EncryptToBase64String(Byte[] data, Byte[] key) {
|
|
return Convert.ToBase64String(Encrypt(data, key));
|
|
}
|
|
|
|
public static String EncryptToBase64String(String data, Byte[] key) {
|
|
return Convert.ToBase64String(Encrypt(data, key));
|
|
}
|
|
|
|
public static String EncryptToBase64String(Byte[] data, String key) {
|
|
return Convert.ToBase64String(Encrypt(data, key));
|
|
}
|
|
|
|
public static String EncryptToBase64String(String data, String key) {
|
|
return Convert.ToBase64String(Encrypt(data, key));
|
|
}
|
|
|
|
public static Byte[] Decrypt(Byte[] data, Byte[] key) {
|
|
if (data.Length == 0) {
|
|
return data;
|
|
}
|
|
return ToByteArray(Decrypt(ToUInt32Array(data, false), ToUInt32Array(FixKey(key), false)), true);
|
|
}
|
|
|
|
public static Byte[] Decrypt(Byte[] data, String key) {
|
|
return Decrypt(data, utf8.GetBytes(key));
|
|
}
|
|
|
|
public static Byte[] DecryptBase64String(String data, Byte[] key) {
|
|
return Decrypt(Convert.FromBase64String(data), key);
|
|
}
|
|
|
|
public static Byte[] DecryptBase64String(String data, String key) {
|
|
return Decrypt(Convert.FromBase64String(data), key);
|
|
}
|
|
|
|
public static String DecryptToString(Byte[] data, Byte[] key) {
|
|
return utf8.GetString(Decrypt(data, key));
|
|
}
|
|
|
|
public static String DecryptToString(Byte[] data, String key) {
|
|
return utf8.GetString(Decrypt(data, key));
|
|
}
|
|
|
|
public static String DecryptBase64StringToString(String data, Byte[] key) {
|
|
return utf8.GetString(DecryptBase64String(data, key));
|
|
}
|
|
|
|
public static String DecryptBase64StringToString(String data, String key) {
|
|
return utf8.GetString(DecryptBase64String(data, key));
|
|
}
|
|
|
|
private static UInt32[] Encrypt(UInt32[] v, UInt32[] k) {
|
|
Int32 n = v.Length - 1;
|
|
if (n < 1) {
|
|
return v;
|
|
}
|
|
UInt32 z = v[n], y, sum = 0, e;
|
|
Int32 p, q = 6 + 52 / (n + 1);
|
|
unchecked {
|
|
while (0 < q--) {
|
|
sum += delta;
|
|
e = sum >> 2 & 3;
|
|
for (p = 0; p < n; p++) {
|
|
y = v[p + 1];
|
|
z = v[p] += MX(sum, y, z, p, e, k);
|
|
}
|
|
y = v[0];
|
|
z = v[n] += MX(sum, y, z, p, e, k);
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
|
|
private static UInt32[] Decrypt(UInt32[] v, UInt32[] k) {
|
|
Int32 n = v.Length - 1;
|
|
if (n < 1) {
|
|
return v;
|
|
}
|
|
UInt32 z, y = v[0], sum, e;
|
|
Int32 p, q = 6 + 52 / (n + 1);
|
|
unchecked {
|
|
sum = (UInt32)(q * delta);
|
|
while (sum != 0) {
|
|
e = sum >> 2 & 3;
|
|
for (p = n; p > 0; p--) {
|
|
z = v[p - 1];
|
|
y = v[p] -= MX(sum, y, z, p, e, k);
|
|
}
|
|
z = v[n];
|
|
y = v[0] -= MX(sum, y, z, p, e, k);
|
|
sum -= delta;
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
|
|
private static Byte[] FixKey(Byte[] key) {
|
|
if (key.Length == 16) return key;
|
|
Byte[] fixedkey = new Byte[16];
|
|
if (key.Length < 16) {
|
|
key.CopyTo(fixedkey, 0);
|
|
}
|
|
else {
|
|
Array.Copy(key, 0, fixedkey, 0, 16);
|
|
}
|
|
return fixedkey;
|
|
}
|
|
|
|
private static UInt32[] ToUInt32Array(Byte[] data, Boolean includeLength) {
|
|
Int32 length = data.Length;
|
|
Int32 n = (((length & 3) == 0) ? (length >> 2) : ((length >> 2) + 1));
|
|
UInt32[] result;
|
|
if (includeLength) {
|
|
result = new UInt32[n + 1];
|
|
result[n] = (UInt32)length;
|
|
}
|
|
else {
|
|
result = new UInt32[n];
|
|
}
|
|
for (Int32 i = 0; i < length; i++) {
|
|
result[i >> 2] |= (UInt32)data[i] << ((i & 3) << 3);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static Byte[] ToByteArray(UInt32[] data, Boolean includeLength) {
|
|
Int32 n = data.Length << 2;
|
|
if (includeLength) {
|
|
Int32 m = (Int32)data[data.Length - 1];
|
|
n -= 4;
|
|
if ((m < n - 3) || (m > n)) {
|
|
return null;
|
|
}
|
|
n = m;
|
|
}
|
|
Byte[] result = new Byte[n];
|
|
for (Int32 i = 0; i < n; i++) {
|
|
result[i] = (Byte)(data[i >> 2] >> ((i & 3) << 3));
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|