注:本人只是从LUMA QQ的 Source Code里面把相应Java语言翻译成C#,纯技术研究,并没有对TC产品做任何逆向分析,不承担任何法律责任!转载请保持本文完整性
网上有c/c++,vb,delphi,java,perl各种版本的tea填充算法,唯独没有C#的,这让我这种狂热喜爱C#的人如何承受,于是,花3天时间看了各种代码经历无数失败的挫折终于用C#完成了该填充算法,废话不多说,直接给代码
/*********************************************************
FILE : QQCrypt.cs
9.22更正:一处笔误造成解密失败的BUG
优化部分代码
**********************************************************/
using
System;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
namespace
RedQ
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//// <summary>
/// QQ Msg En/DeCrypt Class
/// Writen By Red_angelX On 2006.9.13
/// </summary>
public class QQCrypt
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//QQ TEA-16 Encrypt/Decrypt Class
//
//
//And also LumaQQ//s source code
// CopyRight:No CopyRight^_^
// Author : Red_angelX
// NetWork is Free,Tencent is ****!
//
//Class Begin
//AD:Find Job!!,If you Want Give me a Job,Content Me!!
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//Copied & translated from LumaQQ//s source code `From LumaQQ///s source code:
private byte[] Plain; //指向当前的明文块
private byte[] prePlain ; //指向前面一个明文块
private byte[] Out; //输出的密文或者明文
private long Crypt, preCrypt; //当前加密的密文位置和上一次加密的密文块位置,他们相差8
private long Pos; //当前处理的加密解密块的位置
private long padding; //填充数
private byte[] Key = new byte[16]; //密钥
private bool Header; //用于加密时,表示当前是否是第一个8字节块,因为加密算法
//是反馈的,但是最开始的8个字节没有反馈可用,所有需要标
//明这种情况
private long contextStart; //这个表示当前解密开始的位置,之所以要这么一个变量是为了
//避免当解密到最后时后面已经没有数据,这时候就会出错,这
//个变量就是用来判断这种情况免得出错
public QQCrypt()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//
// TODO: 在此处添加构造函数逻辑
//
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//Push 数据
byte[] CopyMemory(byte[] arr,int arr_index,long input) //lenth = 4
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(arr_index+4 > arr.Length)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// 不能执行
return arr;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
arr[arr_index+3]=(byte)((input & 0xff000000) >> 24);
arr[arr_index+2]=(byte)((input & 0x00ff0000) >> 16);
arr[arr_index+1]=(byte)((input & 0x0000ff00) >> 8);
arr[arr_index]=(byte)(input & 0x000000ff);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
arr[arr_index] &= 0xff;
arr[arr_index+1] &= 0xff;
arr[arr_index+2] &= 0xff;
arr[arr_index+3] &= 0xff;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return arr;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
long CopyMemory(long Out,byte[] arr,int arr_index)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if(arr_index+4 > arr.Length)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return Out;
//不能执行
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
long x1 = arr[arr_index+3] << 24;
long x2 = arr[arr_index+2] << 16;
long x3 = arr[arr_index+1] << 8;
long x4 = arr[arr_index];
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
long o = x1 | x2 | x3 | x4;
o &= 0xffffffff;
return o;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
long getUnsignedInt(byte[] arrayIn, int offset,int len /**//*Default is 4*/)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
long ret = 0;
int end = 0;
if (len > 8)
end = offset + 8;
else
end = offset + len;
for (int i = offset; i < end; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
ret <<= 8;
ret |= arrayIn[i] & 0xff;
}
return (ret & 0xffffffff) | (ret >> 32);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
long Rand()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
Random rd = new Random();
long ret;