Web探索|Asp.net||Jquery|MVC

Web前沿技术、移动解决方案
  博客园  :: 首页  :: 新随笔  :: 管理

XXTEA 加密算法

Posted on 2014-09-28 14:34  reckcn  阅读(666)  评论(0编辑  收藏  举报
/*
 * 需要注意的是,这里加密的是字节数组,而不是字符串。因为 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(textBox2.Text), encoder.GetBytes("1234567890abcdef")));
            }
            catch (Exception)
            {
                MessageBox.Show("您的输入不正确!");
            }
        }
    }