/*
* 需要注意的是,這裡加密的是位元組數組,而不是字串。因為 C# 字串是按照 Unicode 編碼儲存的。
* 要加密字串的話,需要用 System.Text.Encoding.UTF8 (或者其他編碼器)的 GetBytes 方法轉化為位元組數組,然後才能對其加密,密鑰也是一樣的。
* 密鑰長度是 128 位,也就是 16 個元素的位元組數組,不過少於 16 個位元組或多於 16 個位元組都可以正常工作,
* 少於 16 個位元組時,會自動通過補零來充填到 16 個位元組,多於 16 個位元組之後的元素會被忽略。
* 另外還需要注意一點,加密以後的內容也是位元組數組,但是你不能用 System.Text.Encoding.UTF8 把它轉化為字串,否則會造成資訊丟失。
* System.Text.Encoding encoder = System.Text.Encoding.UTF8;
* Byte[] data = XXTEA.Encrypt(encoder.GetBytes(textBox1.Text), encoder.GetBytes("1234567890abcdef"));
* textBox2.Text = System.Convert.ToBase64String(data);
* */
using System;
class XXTEA
{
public static Byte[] Encrypt(Byte[] Data, Byte[] Key)
{
if (Data.Length == 0)
{
return Data;
}
return ToByteArray(Encrypt(ToUInt32Array(Data, true), ToUInt32Array(Key, false)), false);
}
public static Byte[] Decrypt(Byte[] Data, Byte[] Key)
{
if (Data.Length == 0)
{
return Data;
}
return ToByteArray(Decrypt(ToUInt32Array(Data, false), ToUInt32Array(Key, false)), true);
}
public static UInt32[] Encrypt(UInt32[] v, UInt32[] k)
{
Int32 n = v.Length - 1;
if (n < 1)
{
return v;
}
if (k.Length < 4)
{
UInt32[] Key = new UInt32[4];
k.CopyTo(Key, 0);
k = Key;
}
UInt32 z = v[n], y = v[0], delta = 0x9E3779B9, sum = 0, e;
Int32 p, q = 6 + 52 / (n + 1);
while (q-- > 0)
{
sum = unchecked(sum + delta);
e = sum >> 2 & 3;
for (p = 0; p < n; p++)
{
y = v[p + 1];
z = unchecked(v[p] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
}
y = v[0];
z = unchecked(v[n] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
}
return v;
}
public static UInt32[] Decrypt(UInt32[] v, UInt32[] k)
{
Int32 n = v.Length - 1;
if (n < 1)
{
return v;
}
if (k.Length < 4)
{
UInt32[] Key = new UInt32[4];
k.CopyTo(Key, 0);
k = Key;
}
UInt32 z = v[n], y = v[0], delta = 0x9E3779B9, sum, e;
Int32 p, q = 6 + 52 / (n + 1);
sum = unchecked((UInt32)(q * delta));
while (sum != 0)
{
e = sum >> 2 & 3;
for (p = n; p > 0; p--)
{
z = v[p - 1];
y = unchecked(v[p] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
}
z = v[n];
y = unchecked(v[0] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
sum = unchecked(sum - delta);
}
return v;
}
private static UInt32[] ToUInt32Array(Byte[] Data, Boolean IncludeLength)
{
Int32 n = (((Data.Length & 3) == 0) ? (Data.Length >> 2) : ((Data.Length >> 2) + 1));
UInt32[] Result;
if (IncludeLength)
{
Result = new UInt32[n + 1];
Result[n] = (UInt32)Data.Length;
}
else
{
Result = new UInt32[n];
}
n = Data.Length;
for (Int32 i = 0; i < n; i++)
{
Result[i >> 2] |= (UInt32)Data[i] << ((i & 3) << 3);
}
return Result;
}
private static Byte[] ToByteArray(UInt32[] Data, Boolean IncludeLength)
{
Int32 n;
if (IncludeLength)
{
n = (Int32)Data[Data.Length - 1];
}
else
{
n = Data.Length << 2;
}
Byte[] Result = new Byte[n];
for (Int32 i = 0; i < n; i++)
{
Result[i] = (Byte)(Data[i >> 2] >> ((i & 3) << 3));
}
return Result;
}
}
調用:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
System.Text.Encoding encoder = System.Text.Encoding.UTF8;
Byte[] data = XXTEA.Encrypt(encoder.GetBytes(textBox1.Text), encoder.GetBytes("1234567890abcdef"));
textBox2.Text = System.Convert.ToBase64String(data);
}
private void button2_Click(object sender, EventArgs e)
{
System.Text.Encoding encoder = System.Text.Encoding.UTF8;
try
{
textBox2.Text = encoder.GetString(XXTEA.Decrypt(System.Convert.FromBase64String(textBox1.Text), encoder.GetBytes("1234567890abcdef")));
}
catch (Exception)
{
MessageBox.Show("您的輸入不正確!");
}
}
}