using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace WindowsFormsApplication1
{
/// <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 > )
{
for (int i = ; i < ; i++)
{
In[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - ]);
}
}
uint[] formattedKey = FormatKey(key);
uint y = ConvertByteArrayToUInt(In, outOffset + outPos);
uint z = ConvertByteArrayToUInt(In, outOffset + outPos + );
uint sum = ;
uint delta = 0x9e3779b9;
uint n = ; while (n-- > )
{
sum += delta;
y += ((z << ) + formattedKey[]) ^ (z + sum) ^ ((z >> ) + formattedKey[]);
z += ((y << ) + formattedKey[]) ^ (y + sum) ^ ((y >> ) + formattedKey[]);
}
Array.Copy(ConvertUIntToByteArray(y), , Out, outOffset + outPos, );
Array.Copy(ConvertUIntToByteArray(z), , Out, outOffset + outPos + , );
if (inPos > )
{
for (int i = ; i < ; i++)
{
Out[outOffset + outPos + i] = (byte)(Out[outOffset + outPos + i] ^ In[inOffset + inPos + i - ]);
}
}
} private static void decode(byte[] In, int inOffset, int inPos, byte[] Out, int outOffset, int outPos, byte[] key)
{
if (outPos > )
{
for (int i = ; i < ; i++)
{
Out[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - ]);
}
}
else
{
Array.Copy(In, inOffset, Out, outOffset, );
}
uint[] formattedKey = FormatKey(key);
uint y = ConvertByteArrayToUInt(Out, outOffset + outPos);
uint z = ConvertByteArrayToUInt(Out, outOffset + outPos + );
uint sum = 0xE3779B90;
uint delta = 0x9e3779b9;
uint n = ; while (n-- > )
{
z -= ((y << ) + formattedKey[]) ^ (y + sum) ^ ((y >> ) + formattedKey[]);
y -= ((z << ) + formattedKey[]) ^ (z + sum) ^ ((z >> ) + formattedKey[]);
sum -= delta;
}
Array.Copy(ConvertUIntToByteArray(y), , Out, outOffset + outPos, );
Array.Copy(ConvertUIntToByteArray(z), , Out, outOffset + outPos + , );
} /**/
/// <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 % != ) || (len < ))
{
return null;
}
byte[] Out = new byte[len];
for (int i = ; i < len; i += )
{
decode(In, offset, i, Out, , i, key);
}
for (int i = ; i < len; i++)
{
Out[i] = (byte)(Out[i] ^ In[offset + i - ]);
}
int pos = Out[] & 0x07;
len = len - pos - ;
byte[] res = new byte[len];
Array.Copy(Out, pos + , res, , len);
return res;
} public static byte[] Encrypt(byte[] In, int offset, int len, byte[] key)
{
// 计算头部填充字节数
int pos = (len + ) % ;
if (pos != )
{
pos = - pos;
}
byte[] plain = new byte[len + pos + ];
Random Rnd = new Random();
plain[] = (byte)((Rnd.Next() & 0xF8) | pos);
for (int i = ; i < pos + ; i++)
{
plain[i] = (byte)(Rnd.Next() & 0xFF);
}
Array.Copy(In, , plain, pos + , len);
for (int i = pos + + len; i < plain.Length; i++)
{
plain[i] = 0x0;
}
// 定义输出流
byte[] outer = new byte[len + pos + ];
for (int i = ; i < outer.Length; i += )
{
code(plain, , i, outer, , i, key);
}
return outer;
} private static uint[] FormatKey(byte[] key)
{
if (key.Length == )
{
throw new ArgumentException("Key must be between 1 and 16 characters in length");
}
byte[] refineKey = new byte[];
if (key.Length < )
{
Array.Copy(key, , refineKey, , key.Length);
for (int k = key.Length; k < ; k++)
{
refineKey[k] = 0x20;
}
}
else
{
Array.Copy(key, , refineKey, , );
}
uint[] formattedKey = new uint[];
int j = ;
for (int i = ; i < refineKey.Length; i += )
{
formattedKey[j++] = ConvertByteArrayToUInt(refineKey, i);
}
return formattedKey;
} private static byte[] ConvertUIntToByteArray(uint v)
{
byte[] result = new byte[];
result[] = (byte)((v >> ) & 0xFF);
result[] = (byte)((v >> ) & 0xFF);
result[] = (byte)((v >> ) & 0xFF);
result[] = (byte)((v >> ) & 0xFF);
return result;
} private static uint ConvertByteArrayToUInt(byte[] v, int offset)
{
if (offset + > v.Length)
{
return ;
}
uint output;
output = (uint)(v[offset] << );
output |= (uint)(v[offset + ] << );
output |= (uint)(v[offset + ] << );
output |= (uint)(v[offset + ] << );
return output;
}
} }

C#版QQTea加密的更多相关文章

  1. 简易版DES加密和解密详解

    在DES密码里,是如何进行加密和解密的呢?这里采用DES的简易版来进行说明. 二进制数据的变换 由于不仅仅是DES密码,在其它的现代密码中也应用了二进制数据,所以无论是文章还是数字,都需要将明文变换为 ...

  2. OpenLdap的加密md5(Java+Python,同时提供明文-->密文,md5(名文)-->密文两种方法)

    # slappasswd -h {md5} -s "secret"{MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ== import base64 import hashli ...

  3. PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support missing的解决方法

    Zend Guard是目前市面上最成熟的PHP源码加密产品了.刚好需要对自己的产品进行加密,折腾了一晚上,终于搞定,将碰到的问题及解决方法记录下来,方便日后需要,也可以帮助其他人.我使用的是Wamps ...

  4. ioncube 加密软件 linux 使用方法

    https://www.ioncube.com/sa_encoder.php?page=pricing 购买成功后 解压文件包 装了一个linux 版的加密软件 目录:/webdata/soft/io ...

  5. 加密文件之Java改进版

    对应Python版:加密文件之Python版Java版比Python版要快得多,两个版本不在一个量级上.在加密解密1G大文件时,Java版花费的时间是秒级,而Python版花费的时间是10分钟级. i ...

  6. asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得

    <?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...

  7. python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题

    python爬虫---详解爬虫分类,HTTP和HTTPS的区别,证书加密,反爬机制和反反爬策略,requests模块的使用,常见的问题 一丶爬虫概述       通过编写程序'模拟浏览器'上网,然后通 ...

  8. robotframework 接口测试 +RSA 加密

    首先,实现RSA加密,需要用到pycrypto这个库,这个库又依赖openssl,所以需要先下载openssl,具体教程可以参考http://bbs.csdn.net/topics/392193545 ...

  9. Base64加密工具

    正常来讲加密基本上永远都要伴随着解密,所谓的加密或者解密,往往都需要有一些规则,在JDK1.8开始,提供有新的加密处理操作类,Base64处理类--Base64类 在该类之中存在两个内部类:Base6 ...

随机推荐

  1. 表格td标签在不添加多余标签的情况下实现文本内容单行显示,多余部分省略号表示的方法

    #table { table-layout: fixed; } .content { white-space: nowrap; text-overflow: ellipsis; -o-text-ove ...

  2. python2 和3的区别

    __future__ 模块 Python 3.x引入一些Python2不兼容的关键字和函数,可以通过在 Python2 内置的模块 __future__ 导入.建议如果你想在代码中支持 Python3 ...

  3. iOS https认证 && SSL/TLS证书申请

    1.下面列出截止2016年底市面上常见的免费CA证书: 腾讯云SSL证书管理(赛门铁克TrustAsia DV SSL证书)阿里云云盾证书服务(赛门铁克DV SSL证书)百度云SSL证书服务Let's ...

  4. 总结一下用caffe跑图片数据的研究流程

    近期在用caffe玩一些数据集,这些数据集是从淘宝爬下来的图片.主要是想研究一下对女性衣服的分类. 以下是一些详细的操作流程,这里总结一下. 1 爬取数据.写爬虫从淘宝爬取自己须要的数据. 2 数据预 ...

  5. Javascript进阶篇——(流程控制语句)笔记整理

    做判断(if语句)if语句是基于条件成立才执行相应代码时使用的语句.语法: if(条件){ 条件成立时执行代码 } 例子:假设你应聘web前端技术开发岗位,如果你会HTML技术,你面试成功,欢迎加入公 ...

  6. VS2003,安装程序检测到另一个程序…

    昨天在安装Visual Studio .Net 2003时,出现一个对话框   "安装程序检测到另一个程序要求计算机重新启动.必须重新启动计算机后才能安装visual studio.net系 ...

  7. ASP.NET MVC请求特殊静态文件返回404 Not Found

    今天在请求静态的json档案以及woff2档案,会返回404错误,需要在Web.Config里修改: <system.webServer> <modules> <remo ...

  8. IOS--工作总结--post上传文件(以流的方式上传)

    1.添加协议 <NSURLConnectionDelegate> 2.创建 @property (nonatomic,retain) NSURLConnection* aSynConnec ...

  9. XMAL 中x名称控件的Auttribute

    1 X:Class 作用告诉XAML编译器将XAML标签的编译结果与后台代码中指定的类合并,只能用于根节点,并且与之同名的类需要有Partial 例如窗口 2 X:ClassModifier 作用告诉 ...

  10. Gengxin讲STL系列——String

    衔接上一篇引导. 作为第一篇博客,就要大气一点. 可我好像并不知道怎么才能让自己的博客大气一点= =: 明天是我生日,自己先买个中文域名庆祝了一下…… 好了,废话说完了,结果博客也没大气到哪去……,正 ...