网上到的qq协议的TEA加密和解密说明如下: 也有很多源代码,但是感觉上代码比较复杂,不容易看。我用C#重写了下。 基于2008协议
    * QQ消息的加密算法是一个16次的迭代过程,并且是反馈的,每一个加密单元是8字节,输出也是8字节,密钥是16字节
    * 我们以prePlain表示前一个明文块,plain表示当前明文块,crypt表示当前明文块加密得到的密文块,preCrypt表示前一个密文块
    * f表示加密算法,d表示解密算法 那么从plain得到crypt的过程是:
      *      crypt = f(plain ^ preCrypt) ^ prePlain
    * 所以,从crypt得到plain的过程自然是
      *      plain = d(crypt ^ prePlain) ^ preCrypt
    * 此外,算法有它的填充机制,其会在明文前和明文后分别填充一定的字节数,以保证明文长度是8字节的倍数
    * 填充的字节数与原始明文长度有关,填充的方法是:
    *
      *      ------- 消息填充算法 -----------
    *      a = (明文长度 + 10) mod 8
    *      if(a 不等于 0) a = 8 - a;
    *      b = 随机数 & 0xF8 | a;              这个的作用是把a的值保存了下来
    *      plain[0] = b;                  然后把b做为明文的第0个字节,这样第0个字节就保存了a的信息,这个信息在解密时就要用来到真正明文的起始位置
    *      plain[1 a+2] = 随机数 & 0xFF;    这里用随机数填充明文的第1到第a+2个字节
    *      plain[a+3 a+3+明文长度-1] = 明文; a+3字节开始才是真正的明文
    *      plain[a+3+明文长度, 最后] = 0;      在最后,填充0,填充到总长度为8的整数为止。到此为止,结束了,这就是最后得到的要加密的明文内容
    *      ------- 消息填充算法 ------------
      /// <summary>      /// 加密解密QQ消息包的工具类.      /// </summary>      public static class QQCrypter      {          private static void code(byte[] In, int inOffset, int inPos, byte[] Out, int outOffset, int outPos, byte[] key)          {              if (outPos > 0)              {                f
or (int i = 0; i < 8; i++)                {                    In[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - 8]);                }            }            uint[] formattedKey = FormatKey(key);            uint y = ConvertByteArrayToUInt(In, outOffset + outPos);            uint z = ConvertByteArrayToUInt(In, outOffset + outPos + 4);            uint sum = 0;            uint delta = 0x9e3779b9;            uint n = 16;              while (n-- > 0)            {                sum += delta;                y += ((z << 4) + formattedKey[0]) ^ (z + sum) ^ ((z >> 5) + formattedKey[1]);                z += ((y << 4) + formattedKey[2]) ^ (y + sum) ^ ((y >> 5) + formattedKey[3]);            }            Array.Copy(ConvertUIntToByteArray(y), 0, Out, outOffset + outPos, 4);            Array.Copy(ConvertUIntToByteArray(z), 0, Out, outOffset + outPos + 4, 4);            if (inPos > 0)            {                for (int i = 0; i < 8; i++)                {                    Out[outOffset + outPos + i] = (byte)(Out[outOffset + outPos + i] ^ In[inOffset + inPos + i - 8]);                }            }        }          private static void decode(byte[] In, int inOffset, int inPos, byte[] Out, int outOffset, int outPos, byte[] key)        {            if (outPos > 0)            {                for (int i = 0; i < 8; i++)                {                    Out[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - 8]);                }            }            else     
怎么看qq加密相册
      {                Array.Copy(In, inOffset, Out, outOffset, 8);            }            uint[] formattedKey = FormatKey(key);            uint y = ConvertByteArrayToUInt(Out, outOffset + outPos);            uint z = ConvertByteArrayToUInt(Out, outOffset + outPos + 4);            uint sum = 0xE3779B90;            uint delta = 0x9e3779b9;            uint n = 16;              while (n-- > 0)            {                z -= ((y << 4) + formattedKey[2]) ^ (y + sum) ^ ((y >> 5) + formattedKey[3]);                y -= ((z << 4) + formattedKey[0]) ^ (z + sum) ^ ((z >> 5) + formattedKey[1]);                sum -= delta;            }            Array.Copy(ConvertUIntToByteArray(y), 0, Out, outOffset + outPos, 4);            Array.Copy(ConvertUIntToByteArray(z), 0, Out, outOffset + outPos + 4, 4);        }          /**//// <summary>        /// 解密        /// </summary>        /// <param name="In">密文</param>        /// <param name="offset">密文开始的位置</param>        /// <param name="len">密文长度</param>        /// <param name="key">密钥</param>        /// <returns>返回明文</returns>        public static byte[] Decrypt(byte[] In, int offset, int len, byte[] key)        {            // 因为QQ消息加密之后至少是16字节,并且肯定是8的倍数,这里检查这种情况            if ((len % 8 != 0) || (len < 16))            {                return null;            }            byte[] Out = new byte[len];            for (int i = 0; i < len; i += 8)            {                decode(I
n, offset, i, Out, 0, i, key);            }            for (int i = 8; i < len; i++)            {                Out[i] = (byte)(Out[i] ^ In[offset + i - 8]);            }            int pos = Out[0] & 0x07;            len = len - pos - 10;            byte[] res = new byte[len];            Array.Copy(Out, pos + 3, res, 0, len);            return res;        }        public static byte[] Encrypt(byte[] In, int offset, int len, byte[] key)        {            // 计算头部填充字节数            int pos = (len + 10) % 8;            if (pos != 0)            {                pos = 8 - pos;            }            byte[] plain = new byte[len + pos + 10];            plain[0] = (byte)((Rnd.Next() & 0xF8) | pos);            for (int i = 1; i < pos + 3; i++)            {                plain[i] = (byte)(Rnd.Next() & 0xFF);            }            Array.Copy(In, 0, plain, pos + 3, len);            for (int i = pos + 3 + len; i < plain.Length; i++)            {                plain[i] =
/a/biancheng/jmjm/wzsf/2012/0915/88190.html