<?xml version="1.0" encoding="utf-8" ?>
<!-- generator="crazycoder cms 1.0(beta)" -->
<rss version="2.0" xmlns:sns="http://www.crazycoder.cn/rss/news">
	<channel>
		<title>QQ协议开发</title>
		<description></description>
		<link>http://CrazyCoder.cn/QQDevelopment/Index.html</link>
		<lastBuildDate>2010-08-01</lastBuildDate>
		<generator>CrazyCoder 1.0(beta)</generator>
		<language>zh-cn</language>
		<copyright>Copyright 1996 - 2008 疯狂代码  All Rights Reserved.</copyright>
		<pubDate>2010-08-01</pubDate>
		<item>
			<title><![CDATA[QQ协议分析,TCPF包数据具体分析]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article20653.html</link>
			<description>
				<![CDATA[
<p><span class="Apple-style-span" style="color: rgb(101, 109, 119); font-family: 宋体; font-size: 14px; line-height: 25px; ">
<p>转载说明：</p>
<p>本文档说明的是解密以后的TCPF数据包的字段内容。有关如何解密，请参阅有关的其它文档。分析的结果，是基于QQ 2003 (0808) 内部代码 0A 1D的版本。</p>
<p>0x0022，登录命令</p>
<p>发送方：客户端</p>
<p>样本：</p>
<p>000: 4A 35 5D 6E AE DB FA 9C&nbsp;<br />
008: 96 BE 19 7E A3 E2 B2 48&nbsp;<br />
016: 00 00 00 00 00 00 00 00&nbsp;<br />
024: 00 00 00 00 00 00 00 00&nbsp;<br />
032: 00 00 00 3A 30 9B 69 60&nbsp;<br />
040: A8 32 73 B2 22 1F AA 65&nbsp;<br />
048: 6C 09 F8 01 0A 3A 0D 30&nbsp;<br />
056: 92 CD 77 AB 42 B9 BC 64&nbsp;<br />
064: 9F 17 57 D4 C3</p>
<p>000 - 015: 用户QQ密码的 <a href='/Tag/16228/Index.html'>md5</a> 的 <a href='/Tag/16228/Index.html'>md5</a> 作为密钥，对空字串进行加密的结果。0A 1D版的TEA算法采取了随机PADDING的方式，所以这个数字每次看起来都不同。但是解密以后总是空字符串。</p>
<p>016 - 016: 总是 0x00。</p>
<p>017 - 020: 以前为IP地址，现在为全零。不知道具有互联网IP的机器是否有真正的地址。</p>
<p>021 - 022: 以前为端口号，现在为全零。</p>
<p>023 - 051: 不明含义，总是相同。</p>
<p>052 - 052: 登录模式。0A为正常方式，28为隐身。</p>
<p>053 - 068: 应该是和机器相关的识别号，在相同的机器上总是相同。</p>
<p>响应方：服务器</p>
<p>成功登录的样本：</p>
<p>000: 00 61 42 58 45 55 6B 58&nbsp;<br />
008: 7A 42 57 36 78 6E 49 41&nbsp;<br />
016: 59 01 82 5D 90 40 E7 A7&nbsp;<br />
024: E3 0F A0 7F 00 00 01 1F&nbsp;<br />
032: 40 3F 51 22 DA 03 0A 5B&nbsp;<br />
040: 83 50 D2 91 55 AE FC 3A&nbsp;<br />
048: 5B D4 E9 31 97 C5 85 13&nbsp;<br />
056: 64 6B 30 0A CE F1 33 3D&nbsp;<br />
064: 8D C2 CF 1F 40 3D AC F9&nbsp;<br />
072: 8E 1F 40 00 00 1C BB 67&nbsp;<br />
080: 00 CB 49 E6 FF B6 FB 01&nbsp;<br />
088: 97 41 6E 96 30 48 76 48&nbsp;<br />
096: EF B8 1D 1E 5A EA EB E9&nbsp;<br />
104: AB 00 4A 23 D2 00 00 00&nbsp;<br />
112: 00 00 00 00 00 00 00 00&nbsp;<br />
120: 00 40 E7 A7 E3 3F 51 22&nbsp;<br />
128: 91 00 00 00 00 00 00 00&nbsp;<br />
136: 00</p>
<p>000 - 000: 成功登录应该为0。</p>
<p>001 - 016: 以后通信的密钥。</p>
<p>017 - 020: 登录的QQ号码。</p>
<p>021 - 026:&nbsp;服务器检测到的客户端的IP地址和端口号。</p>
<p>027 - 032: 127.0.0.1:8000，应该是服务器检测到自己的IP和端口号？作用不明。</p>
<p>033 - 036: 本次登录时间？</p>
<p>......</p>
<p>063 - 068: 一个端口为8000的IP地址，作用不明。</p>
<p>069 - 074: 一个端口为8000的IP地址，这个地址就是DTPF协议组通讯的服务器。</p>
<p>075 - 076: 总是０，应该为分隔。</p>
<p>......</p>
<p>109 - 120: 总是０。</p>
<p>121 - 124: 客户端的IP。（上次登录的IP？）</p>
<p>125 - 128: 上次登录退出时间？</p>
<p>...</p>
<p>129 - 136: 总是0。</p>
<p>其它：未知。</p>
<p><br />
密码错误的样本（用Random Key解密）：</p>
<p>000: 02 C3 DC C2 EB B4 ED CE&nbsp;<br />
008: F3 A3 A1</p>
<p>000 - 000: 密码错误: 02。<br />
001 - 010:&nbsp;字符串&ldquo;密码错误！&rdquo;，GB18030 编码</p>
<p><br />
要求转到其它服务器登录（未观察到，根据perl-OICQ的资料）：</p>
<p>000 - 000: 转到新服务器：01。</p>
<p>001 - 004: 请求的QQ号。</p>
<p>005 - 008: 新的服务器IP。</p>
<p>009 - 010: 新的服务器端口号。</p>
<p><br />
0x0001，注销命令：</p>
<p>发送方：客户端（连续发送4次）</p>
<p>样本：</p>
<p>000: 42 80 D8 9A 5A 03 F8 12&nbsp;<br />
008: 75 1F 50 4C C1 0E E8 A5</p>
<p>000 - 015: QQ密码的 <a href='/Tag/16228/Index.html'>md5</a> 的 <a href='/Tag/16228/Index.html'>md5</a>。</p>
<p><br />
0x001D，未知命令：</p>
<p>发送方：客户端，在登录成功后发送。而且总是连发两个。</p>
<p>第一个样本：</p>
<p>000: 03</p>
<p>000 - 000 ：总是03，应该是子命令。</p>
<p>第二个样本：</p>
<p>000: 04</p>
<p>000 - 000 ：总是04，应该是子命令。</p>
<p>响应方：服务器（定长的响应）</p>
<p>第一个响应样本：</p>
<p>000: 03 00 52 65 76 65 6D 6D&nbsp;<br />
008: 41 35 65 52 54 64 4E 36&nbsp;<br />
016: 64 4B 00 00 00 00 00 00&nbsp;<br />
024: 00 00 00 00 00 00 38 3D&nbsp;<br />
032: 1E 4A 4E 36 53 87 8E B5&nbsp;<br />
040: E0 24 5C 97 80 8C 64 23&nbsp;<br />
048: F4 FF BC 42 69 72 39 1D&nbsp;<br />
056: F6 31 22 65 37 BE 00 D1&nbsp;<br />
064: 8E A6 F8 4C 75 82 F7 B4&nbsp;<br />
072: 49 1F FF 72 3E 26 01 13&nbsp;<br />
080: 1B 18 F6 5A BD 8E 58 00&nbsp;<br />
088: 01 00 00</p>
<p>000 - 000: 03，应该表明是对03号子命令的响应。</p>
<p>001 - 001: 00，应该是分隔。</p>
<p>002 - 017: 16个字符，全由字母和数字组成。</p>
<p>018 - 029: 全0。</p>
<p>030 - 030: 总是38，应该是后面数据的长度。</p>
<p>...</p>
<p>087 - 090: 总是 00 01 00 00。</p>
<p>第二个响应样本：</p>
<p>000: 04 00 43 44 7A 7A 38 63&nbsp;<br />
008: 74 6A 52 55 4B 55 35 43&nbsp;<br />
016: 52 6B 00 00 00 00 00 00&nbsp;<br />
024: 00 00 00 00 00 00 38 A2&nbsp;<br />
032: 5B B9 D3 0E 67 E8 93 BD&nbsp;<br />
040: 0E B4 F6 AE BF 54 47 D7&nbsp;<br />
048: 0F 69 84 5D F2 81 5D D8&nbsp;<br />
056: 12 BF EC 1E 1A 83 D2 58&nbsp;<br />
064: 1D 94 D4 03 EB 91 3B 13&nbsp;<br />
072: A6 B4 66 37 5C A1 96 48&nbsp;<br />
080: 15 8F BD E0 A8 6C 5F 00&nbsp;<br />
088: 01 00 00</p>
<p>000 - 000: 04，应该表明是对04号子命令的响应。</p>
<p><br />
0x0006，获取用户信息：</p>
<p>发送方：客户端</p>
<p>样本：</p>
<p>000: 32 35 33 32 30 38 34 38</p>
<p>需要获取信息的用户QQ号码。ascii字符串形式。</p>
<p>应答方：服务器</p>
<p>样本：</p>
<p>000: 32 35 33 32 30 38 34 38&nbsp;<br />
008: 1E 6A 65 66 66 5F 79 65&nbsp;<br />
016: 63 6E 1E D6 D0 BB AA C8&nbsp;<br />
024: CB C3 F1 B9 B2 BA CD B9&nbsp;<br />
032: FA 1E B9 E3 B6 AB CA A1&nbsp;<br />
040: 1E 35 31 30 30 30 30 1E&nbsp;<br />
048: 64 6F 6E 67 20 66 65 6E&nbsp;<br />
056: 67 20 72 64 2E 20 31 34&nbsp;<br />
064: 35 1E 2D 1E 33 31 1E C4&nbsp;<br />
072: D0 1E 2D 1E 6A 65 66 66&nbsp;<br />
080: 5F 79 65 63 6E 40 73 69&nbsp;<br />
088: 6E 6F 6D 61 63 2E 63 6F&nbsp;<br />
096: 6D 1E 1E 1E 1E 30 1E 1E&nbsp;<br />
104: CD A8 D0 C5 1E 2D 1E 30&nbsp;<br />
112: 1E 1E 1E 32 30 34 1E 31&nbsp;<br />
120: 33 30 30 35 31 36 31 32&nbsp;<br />
128: 34 34 1E 30 1E CF B2 BB&nbsp;<br />
136: B6 BA CD C8 CE BA CE C8&nbsp;<br />
144: CB C1 C4 CC EC A1 A3 1E&nbsp;<br />
152: B9 E3 D6 DD 1E 2D 1E 2D&nbsp;<br />
160: 1E 30 1E 32 1E 30 1E 55&nbsp;<br />
168: 53 54 43 1E 31 32 1E 31&nbsp;<br />
176: 32 1E 32 1E 30 1E 2D</p>
<p>返回的数值由一个个字段组成，数字也是以字符串表示，没有填写的很多为-。每个字段用1E分隔。分别的含义为：</p>
<p>QQ号码，昵称，国家，省，邮政编码，街道地址，电话，年纪，<br />
性别：男女的GB编码。<br />
真实姓名，电子邮件，寻呼编号，寻呼号，寻呼机供应商，寻呼台号，寻呼机类型，<br />
职业，主页，<br />
添加好友认证方式：'0' 不认证，'1' 需认证，'2' 不许添加<br />
未知20，未知21，<br />
头像：0-255的字符串表示，每三个代表一组正常，离开，忙的头像<br />
手机号码，<br />
手机类型：'0' 为无移动QQ，'1'为开通移动QQ。<br />
自我描述：<br />
城市,<br />
未知27，未知28，未知29，<br />
是否公开手机：'0' 公开 '1' 好友 '2' 不公开<br />
是否公开联系方式：'0' 公开 '1' 好友 '2' 不公开<br />
学校，<br />
星座：以下的对应关系，见pagers.plist<br />
生肖，<br />
血型，<br />
QQShow，<br />
未知37。</p>
<p><br />
0x000D，设置状态：</p>
<p>发送者：客户端</p>
<p>样本：</p>
<p>000: 0A 00 00 0</p>
</span></p> <a href="/mypdf/20653.pdf" title="查看 QQ协议分析,TCPF包数据具体分析 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-10-07</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article20653.html</guid>
		</item>
		<item>
			<title><![CDATA[转,C#版QQ机器人组件源码发布（带示例程序）]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11195.html</link>
			<description>
				<![CDATA[
<p>转自博客园开往春天的地铁的博客，非<a href='/Yuanchuang/Index.html'>原创</a> </p>
<p><a href="/QQ机器人.rar">源代码下载</a></p>
<p>&nbsp;</p>
<p><font face="Verdana">(<span style="color: red;">千万别用此程序乱发广告，更不要跟博客园闪存机器人对闪而刷闪存，后果自负，谢谢</span>)</font></p>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238);"><span style="color: rgb(0, 0, 0);"><font face="Verdana">声明：<br />
<span style="color: red;">本程序以学习为目的，不涉及任何商业利益。任何企业和个人与此程序有关的商业行为，请与腾讯公司联系。<br />
本程序的协议分析过程为黑盒方式，必然会存在不准确的地方，故仅供读者参考。<br />
同时，本程序借鉴了很多互联网中流传的技术资料，在这里就不一一列举！</span>&nbsp;</font></span></div>
<font face="Verdana"><br />
<br />
</font>
<p><font face="Verdana"><br />
看到园子里很多朋友对QQ机器人很感兴趣，尤其是c#版本的。<br />
目前C#版本的QQ机器人组件在各大搜索引擎中比较难寻，基于http协议的已经不能再继续使用。</font></p>
<p><font face="Verdana">于是就把手里的一份可以登录、收发消息、显示好友等功能的C#版本的基于Udp(和Tcp)协议的QQ机器人组件源码和使用Demo<span style="color: red;">暂时</span>提供下载。<br />
说明：<br />
1.协议基于2005(<span style="color: red;">已经有朋友分析2009的拉</span>)<br />
2.在核心代码里包含了QQ的大部分<a href='/Tag/16229/Index.html'>事件</a>;<br />
3.如果哪位同学把协议更改为2007后，麻烦您发一份到:overred2005@163.com(请把@替换为#撒，逗你玩)，谢谢<br />
4.<span style="color: red;">如果无法登陆，请换个服务器地址试验一下</span><br />
</font></p>
<p><font face="Verdana"><br />
程序截图：<br />
<img height="536" width="637" border="0" src="/<a href='/web/Index.html'>Web</a>Files/20089/678b4103-c366-4d94-9341-51d11f4f2a2c.jpg" alt="" /><br />
项目截图：<br />
</font></p>
<p><font face="Verdana"><img height="525" width="230" border="0" src="/<a href='/web/Index.html'>Web</a>Files/20089/af1c9bd2-a9a3-4088-93c9-bcbdd27821a3.jpg" alt="" /><br />
<br />
1.此Demo中惊天大Bug就是使用Timer来处理好友消息，这样会导致有时无法接受到消息！<br />
正确的处理是委托加<a href='/Tag/16229/Index.html'>事件</a>，Core中已经提供，大家能用就用吧，我也懒得改了<br />
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<br />
2.欢迎加入博客园QQ机器人研究组交流群：<span style="color: red;">56451610(已满)，群2：<font face="Verdana">56469186(已满)</font></span>，群共享里有部分资料</font></p>
<font face="Verdana"> </font>
<p><font face="Verdana"><br />
如果你想分析协议，提供以下工具：<br />
1.抓包工具：ethereal<br />
2.包调试工具:qqdebugger（群共享里可下载）<br />
3.重量级调试工具:集成于Lumaqq，如图(Pidgin也有)<br />
</font></p>
<p><font face="Verdana"><img height="296" width="315" border="0" src="/<a href='/web/Index.html'>Web</a>Files/20089/77e48577-38dc-4fcc-98ba-df35e645fffe.jpg" alt="" /><img height="387" width="570" border="0" src="/<a href='/web/Index.html'>Web</a>Files/20089/43b0b7dc-a852-4930-8679-ca82a563f855.jpg" alt="" /><br />
<br />
旅程开始了。。。祝贺您一路顺风。。。。</font></p>
<p>&nbsp;</p> <a href="/mypdf/11195.pdf" title="查看 转,C#版QQ机器人组件源码发布（带示例程序） 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-22</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11195.html</guid>
		</item>
		<item>
			<title><![CDATA[C#实现QQ程序的加密算法]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11194.html</link>
			<description>
				<![CDATA[
<p>QQ的加密算法的C#版本</p>
<p>&nbsp;</p>
<p>不说废话了，看代码把 转载请注明出处，谢谢了！</p>
<p><br />
Luma写的 我<a href='/Translate/Index.html'>翻译</a>的<br />
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.Net;<br />
<br />
namespace <a href='/crazycoder/Index.html'>CrazyCoder</a>.QQ<br />
{<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public class Crypter<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 指向当前的明文块<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] plain;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这指向前面一个明文块<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] prePlain;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 输出的密文或者明文<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] outData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 当前加密的密文位置和上一次加密的密文块位置，他们相差8<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int crypt, preCrypt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 当前处理的加密解密块的位置<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 填充数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int padding;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 密钥<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] key;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private bool header = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private int contextStart;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private static byte rand = 0x0;<br />
<a name="entrymore"></a><br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public byte[] encrypt(byte[] inData, int offset, int len, byte[] key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain = new byte[8];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prePlain = new byte[8];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crypt = preCrypt = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.key = key;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;header = true;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 计算头部填充字节数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = (len + 0x0A) % 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos != 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = 8 - pos;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 计算输出的密文长度<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outData = new byte[len + pos + 10];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这里的操作把pos存到了plain的第一个字节里面<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp; 0xF8后面三位是空的，正好留给pos，因为pos是0到7的值，表示文本开始的字节位置<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[0] = (byte)((rand &amp; 0xF8) &amp;#124; pos);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这里用随机产生的数填充plain[1]到plain[pos]之间的内容<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 1; i &lt;= pos; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[i] = (byte)(rand &amp; 0xFF);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这个就是prePlain，第一个8字节块当然没有prePlain，所以我们做一个全0的给第一个8字节块 傲博知识库<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; 8; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prePlain[i] = (byte)(0x0);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 继续填充2个字节的随机数，这个过程中如果满了8字节就加密之 疯狂代码 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (padding &lt;= 2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[pos++] = (byte)(rand &amp; 0xFF);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encrypt8Bytes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 头部填充完了，这里开始填真正的明文了，也是满了8字节就加密，一直到明文读完<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i2 = offset;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (len &gt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[pos++] = inData[i2++];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encrypt8Bytes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 最后填上0，以保证是8字节的倍数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (padding &lt;= 7)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[pos++] = (byte)(0x0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encrypt8Bytes();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return outData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void encrypt8Bytes()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (pos = 0; pos &lt; 8; pos++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (header)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[pos] ^= prePlain[pos];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;plain[pos] ^= outData[preCrypt + pos];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] crypted = encipher(plain);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.Copy(crypted, 0, outData, crypt, 8);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (pos = 0; pos &lt; 8; pos++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outData[crypt + pos] ^= prePlain[pos];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Array.Copy(plain, 0, prePlain, 0, 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;preCrypt = crypt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crypt += 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;header = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public byte[] encrypt(byte[] inData, byte[] key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return encrypt(inData, 0, inData.Length, key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] encipher(byte[] inData)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int loop = 0x10;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint y2 = BitConverter.ToUInt32(inData, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint y =(uint)(IPAddress .NetworkToHostOrder ( y2)&gt;&gt;32);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint z2 = BitConverter.ToUInt32(inData, 4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint z = (uint)(IPAddress.NetworkToHostOrder(z2) &gt;&gt; 32);<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint a2 = BitConverter.ToUInt32(key, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint a = (uint)(IPAddress.NetworkToHostOrder(a2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint b2 = BitConverter.ToUInt32(key, 4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint b = (uint)(IPAddress.NetworkToHostOrder(b2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint c2 = BitConverter.ToUInt32(key, 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint c = (uint)(IPAddress.NetworkToHostOrder(c2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint d2 = BitConverter.ToUInt32(key, 12);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint d = (uint)(IPAddress.NetworkToHostOrder(d2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint sum = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint delta = 0x9E3779B9;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (loop-- &gt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum += delta;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y += ((z &lt;&lt; 4) + a) ^ (z + sum) ^ ((z &gt;&gt; 5) + b);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;z += ((y &lt;&lt; 4) + c) ^ (y + sum) ^ ((y &gt;&gt; 5) + d);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] ret = new byte[8];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[3] = (byte)y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[2] = (byte)(y &gt;&gt; 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[1] = (byte)(y &gt;&gt; 16);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[0] = (byte)(y &gt;&gt; 24);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[7] = (byte)z;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[6] = (byte)(z &gt;&gt; 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[5] = (byte)(z &gt;&gt; 16);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[4] = (byte)(z &gt;&gt; 24);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public byte[] decrypt(byte[] inData, int offset, int len, byte[] key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crypt = preCrypt = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.key = key;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int count;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] m = new byte[offset + 8];<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((len % 8 != 0) &amp;#124;&amp;#124; (len &lt; 16))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prePlain = decipher(inData, offset);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = prePlain[0] &amp; 0x7;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 得到真正明文的长度<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count = len - pos - 10;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 如果明文长度小于0，那肯定是出错了，比如传输错误之类的，返回<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (count &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这个是临时的preCrypt，和加密时第一个8字节块没有prePlain一样，解密时<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp; 第一个8字节块也没有preCrypt，所有这里建一个全0的<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = offset; i &lt; m.Length; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m[i] = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 通过了上面的代码，密文应该是没有问题了，我们分配输出缓冲区<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outData = new byte[count];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 设置preCrypt的位置等于0，注意目前的preCrypt位置是指向m的，因为<a href='/Java/Index.html'>Java</a>没有指针，所以我们在后面要控制当前密文buf的引用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;preCrypt = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 当前的密文位置，为什么是8不是0呢？注意前面我们已经解密了头部信息了，现在当然该8了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crypt = 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 自然这个也是8<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contextStart = 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 加1，和加密算法是对应的<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos++;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 开始跳过头部，如果在这个过程中满了8字节，则解密下一块<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 因为是解密下一块，所以我们有一个语句 m = in，下一块当然有preCrypt了，我们不再用m了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 但是如果不满8，这说明了什么？说明了头8个字节的密文是包含了明文信息的，当然还是要用m把明文弄出来<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 所以，很显然，满了8的话，说明了头8个字节的密文除了一个长度信息有用之外，其他都是无用的填充<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding = 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (padding &lt;= 2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;padding++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m = inData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!decrypt8Bytes(inData, offset, len))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这里是解密的重要阶段，这个时候头部的填充都已经跳过了，开始解密<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 注意如果上面一个while没有满8，这里第一个if里面用的就是原始的m，否则这个m就是in了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i2 = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (count != 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outData[i2] = (byte)(m[offset + preCrypt + pos] ^ prePlain[pos]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i2++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count--;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m = inData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;preCrypt = crypt - 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!decrypt8Bytes(inData, offset, len))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 最后的解密部分，上面一个while已经把明文都解出来了，到了这里还剩下什么？对了，还剩下尾部的填充，应该全是0<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 所以这里有检查是否解密了之后是0，如果不是的话那肯定出错了，所以返回null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (padding = 1; padding &lt; 8; padding++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos &lt; 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((m[offset + preCrypt + pos] ^ prePlain[pos]) != 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (pos == 8)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m = inData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;preCrypt = crypt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!decrypt8Bytes(inData, offset, len))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return outData;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private bool decrypt8Bytes(byte[] inData, int offset, int len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这里第一步就是判断后面还有没有数据，没有就返回，如果有，就执行 crypt ^ prePlain<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (pos = 0; pos &lt; 8; pos++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (contextStart + pos &gt;= len)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prePlain[pos] ^= inData[offset + crypt + pos];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 好，这里执行到了 d(crypt ^ prePlain)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prePlain = decipher(prePlain);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (prePlain == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 解密完成，wait，没完成哦，最后一步没做哦？ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这里最后一步放到decrypt里面去做了，因为解密的步骤毕竟还是不太一样嘛<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 调整这些变量的值先<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contextStart += 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;crypt += 8;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pos = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public byte[] decrypt(byte[] inData, byte[] key)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return decrypt(inData, 0, inData.Length, key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] decipher(byte[] inData, int offset)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//int loop = 0x10;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint y = BitConverter.ToUInt32(inData, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint z = BitConverter.ToUInt32(inData, 4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint a = BitConverter.ToUInt32(key, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint b = BitConverter.ToUInt32(key, 4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint c = BitConverter.ToUInt32(key, 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint d = BitConverter.ToUInt32(key, 12);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint sum = 0xE3779B90;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//uint delta = 0x9E3779B9;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int loop = 0x10;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint y2 = BitConverter.ToUInt32(inData, offset);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint y = (uint)(IPAddress.NetworkToHostOrder(y2) &gt;&gt; 32);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint z2 = BitConverter.ToUInt32(inData, offset+4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint z = (uint)(IPAddress.NetworkToHostOrder(z2) &gt;&gt; 32);<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint a2 = BitConverter.ToUInt32(key, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint a = (uint)(IPAddress.NetworkToHostOrder(a2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint b2 = BitConverter.ToUInt32(key, 4);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint b = (uint)(IPAddress.NetworkToHostOrder(b2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint c2 = BitConverter.ToUInt32(key, 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint c = (uint)(IPAddress.NetworkToHostOrder(c2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint d2 = BitConverter.ToUInt32(key, 12);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint d = (uint)(IPAddress.NetworkToHostOrder(d2) &gt;&gt; 32);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint sum = 0xE3779B90;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint delta = 0x9E3779B9;<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (loop-- &gt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;z -= ((y &lt;&lt; 4) + c) ^ (y + sum) ^ ((y &gt;&gt; 5) + d);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y -= ((z &lt;&lt; 4) + a) ^ (z + sum) ^ ((z &gt;&gt; 5) + b);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum -= delta;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] ret = new byte[8];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[3] = (byte)y;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[2] = (byte)(y &gt;&gt; 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[1] = (byte)(y &gt;&gt; 16);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[0] = (byte)(y &gt;&gt; 24);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[7] = (byte)z;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[6] = (byte)(z &gt;&gt; 8);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[5] = (byte)(z &gt;&gt; 16);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret[4] = (byte)(z &gt;&gt; 24);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;<br />
<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; 解密<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// by http://www.<a href='/crazycoder/Index.html'>CrazyCoder</a>.cn/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;&quot;&gt;in<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 密文<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/param&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 明文<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/returns&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private byte[] decipher(byte[] inData)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return decipher(inData, 0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; 这是个随机因子产生器，用来填充头部的，如果为了调试，可以用一个固定值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 随机因子可以使相同的明文每次加密出来的密文都不一样 比如傲博知识库类似的<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 随机因子<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/returns&gt;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static Crypter()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//public static int urshift(uint number, int bits)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//{</p>
<p>//by&nbsp; www.<a href='/crazycoder/Index.html'>CrazyCoder</a>.cn<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;if (number &gt;= 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return number &gt;&gt; bits;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (number &gt;&gt; bits) + (uint)(2 &lt;&lt; ~bits);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</p> <a href="/mypdf/11194.pdf" title="查看 C#实现QQ程序的加密算法 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11194.html</guid>
		</item>
		<item>
			<title><![CDATA[C#写的基于http协议的QQ聊天机器人]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11193.html</link>
			<description>
				<![CDATA[
<p>下载源代码</p>
<p><a href="/UploadFiles/QQ机器人源代码_<a href='/crazycoder/Index.html'>CrazyCoder</a>_CN.rar">QQ机器人源代码_<a href='/crazycoder/Index.html'>CrazyCoder</a>_CN.rar</a></p>
<p><font size="3"> 分析QQ协议具体数据包，最简单的办法，是Http接口下手，于是把我以前写的<a href='/Ajax/Index.html'>Ajax</a>给拆了，在把所谓的qq接口研究成果给鼓捣在一起，然后去 <a href='/web/Index.html'>Web</a>qq(</font><a target="_blank" href="http://<a href='/web/Index.html'>Web</a>qq.qq.com/"><font size="3">http://<a href='/web/Index.html'>Web</a>qq.qq.com</font></a><font size="3">)上大抢一遍，那家伙，天昏地暗，相当的&amp;(&amp;(。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;代码我是用script写的：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 异步<a href='/Ajax/Index.html'>Ajax</a>会话类<br />
&nbsp;&nbsp;1//异步<a href='/Ajax/Index.html'>Ajax</a>会话类<br />
&nbsp;&nbsp;2if(typeof(<a href='/Ajax/Index.html'>Ajax</a>Session) == 'undefined')<br />
&nbsp;&nbsp;3var <a href='/Ajax/Index.html'>Ajax</a>Session = function(){<br />
&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;//创建会话<br />
&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;this.CreateSession = function()<br />
&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (window.ActiveXObject){&nbsp;&nbsp;// IE<br />
&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{&nbsp;&nbsp;&nbsp;&nbsp;<br />
10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ActiveXObject('Microsoft.<a href='/Tag/111/Index.html'>xml</a>HTTP');<br />
11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(e){}<br />
12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{ <br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new ActiveXObject('Ms<a href='/Tag/111/Index.html'>xml</a>2.<a href='/Tag/111/Index.html'>xml</a>HTTP');<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(ee){}<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}else{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Mozilla, Safari<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var s = new <a href='/Tag/111/Index.html'>xml</a>HttpRequest(); <br />
18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (s.readyState == null) {<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.readyState = 1;<br />
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.addEventListener(&quot;load&quot;, function () {<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.readyState = 4;<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (typeof(s.onreadystatechange) == &quot;function&quot;)<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.onreadystatechange();<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}, false);<br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s;<br />
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br />
31&nbsp;&nbsp;&nbsp;&nbsp;}<br />
32&nbsp;&nbsp;&nbsp;&nbsp;<br />
33&nbsp;&nbsp;&nbsp;&nbsp;//进行请求<br />
34&nbsp;&nbsp;&nbsp;&nbsp;this.Request = function(url, params, callback)<br />
35&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<br />
36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var s = this.CreateSession();<br />
38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(null == s)<br />
39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;对不起，您的浏览器不支持某些特性。&quot;);<br />
40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.abort();<br />
42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var isAsync =&nbsp;&nbsp;typeof(callback) == 'function';<br />
44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method = !params ? &quot;GET&quot; : &quot;POST&quot;;<br />
45<br />
46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isAsync) s.onreadystatechange = function()<br />
47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br />
49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(s.status);<br />
50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((4 == s.readyState) &amp;&amp; (200 == s.status || 304 == s.status))<br />
51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callback(this.Response(s));<br />
52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;请求错误,错误原因：&quot; + s.statusText);&nbsp;&nbsp;&nbsp;&nbsp;<br />
54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(e){}<br />
55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.open(method, url, isAsync);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.setRequestHeader(&quot;Connection&quot;,&quot;Keep-Alive&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.setRequestHeader(&quot;Content-Type&quot;,&quot;text/html; charset=gb2312&quot;);<br />
60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//s.setRequestHeader(&quot;Content-Type&quot;,&quot;text/plain; charset=UTF-8&quot;);<br />
61&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
62&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(method == &quot;POST&quot;)<br />
63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.setRequestHeader(&quot;Content-Length&quot;,params.length)<br />
65&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.setRequestHeader(&quot;Content-Type&quot;,&quot;application/x-www-form-urlencoded&quot;);<br />
66&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
67&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
68<br />
69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(params);<br />
70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.send(params);<br />
71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!isAsync)<br />
74&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;this.Response(s);<br />
75&nbsp;&nbsp;&nbsp;&nbsp;}<br />
76&nbsp;&nbsp;&nbsp;&nbsp;<br />
77&nbsp;&nbsp;&nbsp;&nbsp;//返回应答信息 疯狂代码<br />
78&nbsp;&nbsp;&nbsp;&nbsp;this.Response = function(s)<br />
79&nbsp;&nbsp;&nbsp;&nbsp;{<br />
80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(s.status == 200&nbsp;&nbsp;|| 304 == s.status)<br />
81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(s.response<a href='/Tag/111/Index.html'>xml</a> != null &amp;&amp; s.response<a href='/Tag/111/Index.html'>xml</a>.<a href='/Tag/111/Index.html'>xml</a> != null &amp;&amp; s.response<a href='/Tag/111/Index.html'>xml</a>.<a href='/Tag/111/Index.html'>xml</a> != '')<br />
83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s.response<a href='/Tag/111/Index.html'>xml</a>;<br />
84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
85&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s.responseText;<br />
86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br />
87&nbsp;&nbsp;&nbsp;&nbsp;}<br />
88&nbsp;&nbsp;&nbsp;&nbsp;<br />
89&nbsp;&nbsp;&nbsp;&nbsp;//对字符串进行编码<br />
90&nbsp;&nbsp;&nbsp;&nbsp;this.UncCoding = function(s) <br />
91&nbsp;&nbsp;&nbsp;&nbsp;{<br />
92&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var utput = '';<br />
93&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0 ;i&lt; s.length;i++){<br />
94&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output = output + '%' + s.charCodeAt(i);<br />
95&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
96<br />
97&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return output; <br />
98&nbsp;&nbsp;&nbsp;&nbsp;}<br />
99<br />
100&nbsp;&nbsp;&nbsp;&nbsp;//获取<a href='/Tag/111/Index.html'>xml</a>结构 傲博知识库<br />
101&nbsp;&nbsp;&nbsp;&nbsp;this.GetDom = function(s){<br />
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var doc = new ActiveXObject('Microsoft.<a href='/Tag/111/Index.html'>xml</a>DOM'); <br />
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc.async = false;<br />
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doc.load<a href='/Tag/111/Index.html'>xml</a>(s) ;&nbsp;&nbsp;&nbsp;&nbsp;<br />
105&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return doc;<br />
106&nbsp;&nbsp;&nbsp;&nbsp;} <br />
107&nbsp;&nbsp;&nbsp;&nbsp;<br />
108&nbsp;&nbsp;&nbsp;&nbsp;return this;<br />
109}<br />
//QQ会话类<br />
1//会话类<br />
2if(typeof(QQSession) == 'undefined')<br />
3var QQSession = function(){<br />
4&nbsp;&nbsp;&nbsp;&nbsp;this.UIN = 0;<br />
5&nbsp;&nbsp;&nbsp;&nbsp;this.<a href='/Tag/16228/Index.html'>md5</a>PasswordStr = &quot;&quot;;<br />
6&nbsp;&nbsp;&nbsp;&nbsp;this.<a href='/web/Index.html'>Web</a>QQUrl = &quot;</font><a target="_blank" href="http://tqq.tencent.com:8000/"><font size="3">http://tqq.tencent.com:8000/</font></a><font size="3">&quot;;<br />
7&nbsp;&nbsp;&nbsp;&nbsp;this.qs = null;&nbsp;&nbsp;&nbsp;&nbsp;<br />
8&nbsp;&nbsp;&nbsp;&nbsp;this.isLogin = false; <br />
9&nbsp;&nbsp;&nbsp;&nbsp;this.SeqIndex = null;<br />
10&nbsp;&nbsp;&nbsp;&nbsp;<br />
11&nbsp;&nbsp;&nbsp;&nbsp;//用户登陆<br />
12&nbsp;&nbsp;&nbsp;&nbsp;this.Login = function(uin,passwd,vcode,qs){<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var m5 = new <a href='/Tag/16228/Index.html'>md5</a>();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.UIN = uin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.<a href='/Tag/16228/Index.html'>md5</a>PasswordStr = m5.calc<a href='/Tag/16228/Index.html'>md5</a>(passwd);<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var CmdStr = &quot;VER=1.0&amp;CMD=1&amp;SEQ=&quot; + this.GetNewSEQ() + &quot;&amp;UIN=&quot; + uin + &quot;&amp;PS=&quot; + this.<a href='/Tag/16228/Index.html'>md5</a>PasswordStr + &quot;&amp;STATUS=10&amp;VCODE=&quot; + vcode + &quot;&amp;QQSESSION=&quot; + qs ;&nbsp;&nbsp;&nbsp;&nbsp;<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//if(!this.qs)<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;this.qs = new <a href='/Ajax/Index.html'>Ajax</a>Session();<br />
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.frames[&quot;proxy&quot;].request(this.<a href='/web/Index.html'>Web</a>QQUrl,CmdStr);<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//this.qs.Request(this.<a href='/web/Index.html'>Web</a>QQUrl,CmdStr,this.ShowMsg);<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//document.getElementById(&quot;ssl_login&quot;).callback = this.ShowMsg;<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//document.getElementById(&quot;ssl_login&quot;).src = &quot;</font><a target="_blank" href="https://<a href='/web/Index.html'>Web</a>qq-proxy.qq.com/<a href='/web/Index.html'>Web</a>qq/l?"><font size="3">https://<a href='/web/Index.html'>Web</a>qq-proxy.qq.com/<a href='/web/Index.html'>Web</a>qq/l?</font></a><font size="3">&quot;+ CmdStr;<br />
25&nbsp;&nbsp;&nbsp;&nbsp;}<br />
26&nbsp;&nbsp;&nbsp;&nbsp;<br />
27&nbsp;&nbsp;&nbsp;&nbsp;//用户信息<br />
28&nbsp;&nbsp;&nbsp;&nbsp;this.GetInfo = function(){<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var CmdStr = &quot;VER=1.0&amp;CMD=10&amp;SEQ=&quot; + this.GetNewSEQ() + &quot;&amp;UIN=&quot; + this.UIN + &quot;&amp;FUIN=&quot; + this.UIN;<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.qs.Request(this.<a href='/web/Index.html'>Web</a>QQUrl,CmdStr,this.ShowMsg);&nbsp;&nbsp;&nbsp;&nbsp;<br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//window.frames[&quot;proxy&quot;].request(this.<a href='/web/Index.html'>Web</a>QQUrl,CmdStr);<br />
32&nbsp;&nbsp;&nbsp;&nbsp;}<br />
33&nbsp;&nbsp;&nbsp;&nbsp;<br />
34&nbsp;&nbsp;&nbsp;&nbsp;//获取好友列表<br />
35&nbsp;&nbsp;&nbsp;&nbsp;this.GetList = function(){<br />
36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var CmdStr = &quot;VER=1.0&amp;CMD=2&amp;SEQ=&quot; + this.GetNewSEQ() + &quot;&amp;UIN=&quot; + this.UIN + &quot;&amp;NPOS=0&quot;;<br />
37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.qs.Request(this.<a href='/web/Index.html'>Web</a>QQUrl,CmdStr,this.ShowMsg);&nbsp;&nbsp;&nbsp;&nbsp;<br />
38&nbsp;&nbsp;&nbsp;&nbsp;}<br />
39&nbsp;&nbsp;&nbsp;&nbsp;<br />
40&nbsp;&nbsp;&nbsp;&nbsp;//获得新的SEQ <a href='/crazycoder/Index.html'>CrazyCoder</a>.cn<br />
41&nbsp;&nbsp;&nbsp;&nbsp;this.GetNewSEQ = function(){<br />
42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!this.SeqIndex){<br />
43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var d = new Date();<br />
44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.SeqIndex = d.getTime()<br />
45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.SeqIndex ++;<br />
48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.SeqIndex;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
49&nbsp;&nbsp;&nbsp;&nbsp;}<br />
50&nbsp;&nbsp;&nbsp;&nbsp;<br />
51&nbsp;&nbsp;&nbsp;&nbsp;this.ShowMsg = function(s){<br />
52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(s);<br />
53&nbsp;&nbsp;&nbsp;&nbsp;}<br />
54&nbsp;&nbsp;&nbsp;&nbsp;<br />
55&nbsp;&nbsp;&nbsp;&nbsp;return this;<br />
56}<br />
&nbsp;&nbsp;&nbsp;&nbsp; 我在那用天真的眼神，盼望着能从这个地方掏出点东西来。可偏偏我这个比较倒霉的孩子，碰到了极其复杂的网络问题（家穷人丑，只好用手机上网，速度回到上世纪90年代），掏了半天啥也没弄到，返回的尽是12152错误。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 去翻MSDN时，遇到几个头疼的单词（鄙人英语着实差劲，单词量屈指可数），很习惯的就去开金山词霸。等等，金山词霸能把别的窗口的信息给拽出来，为什么我就不能。于是我就抛弃了前面的工作，从QQ对话窗口下手。nndx，偶就不信了，偶还灭不了你。<br />
&nbsp;&nbsp;说干就干，那就先勾吧，.net好象是干不了这事,但是winapi还是能干这活的。win32编程嘛，不就几个消息循环（&mdash;（&mdash;&hellip;&hellip;*（&mdash;<br />
WinApi调用<br />
&nbsp;&nbsp;1using System;<br />
&nbsp;&nbsp;2using System.Drawing;<br />
&nbsp;&nbsp;3using System.Runtime.InteropServices;<br />
&nbsp;&nbsp;4<br />
&nbsp;&nbsp;5namespace TQQ<br />
&nbsp;&nbsp;6{<br />
&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;/// WinApi调用<br />
&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
10&nbsp;&nbsp;&nbsp;&nbsp;public class WinApi<br />
11&nbsp;&nbsp;&nbsp;&nbsp;{<br />
12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 根据鼠标位置获取窗体<br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpPoint&quot;&gt;&lt;/param&gt;<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;)]<br />
18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern IntPtr WindowFromPoint(Point lpPoint);<br />
19<br />
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 获取鼠标位置<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpPoint&quot;&gt;&lt;/param&gt;<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;)]<br />
26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int GetCursorPos(out Point lpPoint);<br />
27<br />
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 获取鼠标位置下的窗体<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static IntPtr GetLocalWindow()<br />
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point point;<br />
35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetCursorPos(out point);<br />
36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return WindowFromPoint(point);<br />
37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
38<br />
39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 申请内存空间<br />
41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hProcess&quot;&gt;&lt;/param&gt;<br />
43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpAddress&quot;&gt;&lt;/param&gt;<br />
44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;dwSize&quot;&gt;&lt;/param&gt;<br />
45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;flAllocationType&quot;&gt;&lt;/param&gt;<br />
46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;flProtect&quot;&gt;&lt;/param&gt;<br />
47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ DllImport( &quot;Kernel32.dll&quot; )]<br />
49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern Int32 VirtualAllocEx(IntPtr hProcess,Int32 lpAddress,Int32 dwSize,Int16 flAllocationType,Int16 flProtect);<br />
50<br />
51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 读取内存空间<br />
53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
54&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hProcess&quot;&gt;&lt;/param&gt;<br />
55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpBaseAddress&quot;&gt;&lt;/param&gt;<br />
56&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpBuffer&quot;&gt;&lt;/param&gt;<br />
57&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;nSize&quot;&gt;&lt;/param&gt;<br />
58&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpNumberOfBytesWritten&quot;&gt;&lt;/param&gt;<br />
59&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
60&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ DllImport( &quot;Kernel32.dll&quot; )]<br />
61&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int ReadProcessMemory(IntPtr hProcess, Int32 lpBaseAddress,byte[] lpBuffer,long nSize,long lpNumberOfBytesWritten);<br />
62<br />
63&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 写内存空间<br />
65&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
66&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hProcess&quot;&gt;&lt;/param&gt;<br />
67&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpBaseAddress&quot;&gt;&lt;/param&gt;<br />
68&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpBuffer&quot;&gt;&lt;/param&gt;<br />
69&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;nSize&quot;&gt;&lt;/param&gt;<br />
70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpNumberOfBytesWritten&quot;&gt;&lt;/param&gt;<br />
71&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
72&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ DllImport( &quot;Kernel32.dll&quot; )]<br />
73&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int WriteProcessMemory(IntPtr hProcess, Int32 lpBaseAddress,byte[] lpBuffer,long nSize,long lpNumberOfBytesWritten);<br />
74<br />
75&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
76&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 根据类/标题查找窗口<br />
77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
78&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpClassName&quot;&gt;&lt;/param&gt;<br />
79&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpWindowName&quot;&gt;&lt;/param&gt;<br />
80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
81&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;User32.dll&quot;,EntryPoint=&quot;FindWindow&quot;)]<br />
82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);<br />
83<br />
84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
85&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 获取窗口子对象<br />
86&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
87&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hwndParent&quot;&gt;&lt;/param&gt;<br />
88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hwndChildAfter&quot;&gt;&lt;/param&gt;<br />
89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpszClass&quot;&gt;&lt;/param&gt;<br />
90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lpszWindow&quot;&gt;&lt;/param&gt;<br />
91&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
92&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;,EntryPoint=&quot;FindWindowEx&quot;)]<br />
93&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter, string lpszClass, string lpszWindow);<br />
94<br />
95&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
96&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送windows消息<br />
97&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
98&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hWnd&quot;&gt;&lt;/param&gt;<br />
99&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;Msg&quot;&gt;&lt;/param&gt;<br />
100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wParam&quot;&gt;&lt;/param&gt;<br />
101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lParam&quot;&gt;&lt;/param&gt;<br />
102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;User32.dll&quot;)]<br />
104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern IntPtr SendMessage(IntPtr hWnd,int Msg,IntPtr wParam,IntPtr lParam);<br />
105<br />
106&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
107&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送windows消息<br />
108&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
109&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hWnd&quot;&gt;&lt;/param&gt;<br />
110&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;Msg&quot;&gt;&lt;/param&gt;<br />
111&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wParam&quot;&gt;&lt;/param&gt;<br />
112&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lParam&quot;&gt;&lt;/param&gt;<br />
113&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
114&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;User32.dll&quot;,EntryPoint=&quot;SendMessage&quot;)]<br />
115&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int SendMessage(IntPtr hWnd,int Msg, IntPtr wParam, string lParam);<br />
116<br />
117&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
118&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送windows消息<br />
119&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
120&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hwnd&quot;&gt;&lt;/param&gt;<br />
121&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wMsg&quot;&gt;&lt;/param&gt;<br />
122&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wParam&quot;&gt;&lt;/param&gt;<br />
123&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lParam&quot;&gt;&lt;/param&gt;<br />
124&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
125&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;, CharSet = CharSet.Auto)]<br />
126&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,string lParam);<br />
127<br />
128&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
129&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送windows消息<br />
130&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
131&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hwnd&quot;&gt;&lt;/param&gt;<br />
132&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wMsg&quot;&gt;&lt;/param&gt;<br />
133&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wParam&quot;&gt;&lt;/param&gt;<br />
134&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lParam&quot;&gt;&lt;/param&gt;<br />
135&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
136&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;, CharSet = CharSet.Auto)]<br />
137&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,int lParam);<br />
138<br />
139&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
140&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送windows消息<br />
141&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
142&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;hwnd&quot;&gt;&lt;/param&gt;<br />
143&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wMsg&quot;&gt;&lt;/param&gt;<br />
144&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;wParam&quot;&gt;&lt;/param&gt;<br />
145&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;lParam&quot;&gt;&lt;/param&gt;<br />
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&quot;user32.dll&quot;, CharSet = CharSet.Auto)]<br />
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static extern int SendMessage( IntPtr hwnd, int wMsg, int wParam,System.Text.StringBuilder lParam);<br />
149<br />
150&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int WM_GETTEXT = 0x000D;<br />
151&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int WM_GETTEXTLENGTH = 0x000E;<br />
152&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int WM_SETTEXT = 0x000C;<br />
153&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int WM_CLICK = 0x00F5;<br />
154&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int WM_CHAR = 0x0102;<br />
155&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int EM_SETSEL = 0x00B1;<br />
156&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public const int EM_REPLACESEL = 0x00C2;<br />
157<br />
158&nbsp;&nbsp;&nbsp;&nbsp;}<br />
159}QQ钩子<br />
1/**//// &lt;summary&gt;<br />
2&nbsp;&nbsp;&nbsp;&nbsp;/// QQ钩子<br />
3&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
4&nbsp;&nbsp;&nbsp;&nbsp;public class QQHooks<br />
5&nbsp;&nbsp;&nbsp;&nbsp;{<br />
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 发送消息<br />
8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;windowName&quot;&gt;窗口标题&lt;/param&gt;<br />
10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;strMsg&quot;&gt;消息内容&lt;/param&gt;<br />
11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void SendMsg(string windowName,string strMsg)<br />
12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszParentClass = &quot;#32770&quot;; //整个窗口的类名<br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszParentWindow = windowName; //窗口标题<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr ip = WinApi.FindWindow(lpszParentClass,lpszParentWindow);&nbsp;&nbsp;&nbsp;&nbsp;<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr EdithParentWnd = WinApi.FindWindowEx(ip,new IntPtr(0),&quot;#32770&quot;,&quot;&quot;);<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr EdithWnd = WinApi.FindWindowEx(EdithParentWnd,new IntPtr(0),&quot;AfxWnd42&quot;,&quot;&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
18<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszClass_Text = &quot;RICHEDIT&quot;; //消息输入窗口<br />
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszName_Text = &quot;&quot;; //消息输入窗口<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr THandle = WinApi.FindWindowEx(EdithWnd,new IntPtr(0),lpszClass_Text,lpszName_Text);<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuilder sb = new StringBuilder(strMsg);<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinApi.SendMessage(THandle,WinApi.EM_SETSEL,-1,-1);//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinApi.SendMessage(THandle,WinApi.EM_REPLACESEL,0,sb);<br />
26<br />
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszClass_Submit = &quot;Button&quot;; //需要查找的Button的类名<br />
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszName_Submit = &quot;发送(&amp;S)&quot;; //需要查找的Button的标题<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr TButtonHandle =&nbsp;&nbsp;WinApi.FindWindowEx(EdithParentWnd,new IntPtr(0),lpszClass_Submit,lpszName_Submit);<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinApi.SendMessage(TButtonHandle,WinApi.WM_CLICK,new IntPtr(0),&quot;&quot;);//发送消息到目标控件使它执行click<a href='/Tag/16229/Index.html'>事件</a><br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
32<br />
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 获取消息<br />
35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;windowName&quot;&gt;窗口标题&lt;/param&gt;<br />
37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br />
38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static string GetMsg(string windowName)<br />
39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszParentClass = &quot;#32770&quot;; //整个窗口的类名<br />
41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszParentWindow = windowName; //窗口标题<br />
42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr ip = WinApi.FindWindow(lpszParentClass,lpszParentWindow);&nbsp;&nbsp;&nbsp;&nbsp;<br />
43&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr EdithWnd = WinApi.FindWindowEx(ip,new IntPtr(0),&quot;#32770&quot;,&quot;&quot;);<br />
44<br />
45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszClass_Text = &quot;RichEdit20A&quot;; //查找历史记录类<br />
46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string lpszName_Text = &quot;&quot;; //查找历史记录类的标题<br />
47&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntPtr THandle = WinApi.FindWindowEx(EdithWnd,new IntPtr(0),lpszClass_Text,lpszName_Text);<br />
48<br />
49&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuilder sb = new StringBuilder(300000);<br />
50&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinApi.SendMessage(THandle,WinApi.WM_GETTEXT,255,sb);//发送消息到目标控件&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinApi.SendMessage(THandle,WinApi.WM_SETTEXT,0,&quot;&quot;);<br />
52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return sb.ToString();<br />
53&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
54&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
东西到手了，传话筒的工作基本上算是完成了，接下来就让它显示出来： <br />
1&nbsp;&nbsp;&nbsp;&nbsp;/**//// &lt;summary&gt;<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 时钟<a href='/Tag/16229/Index.html'>事件</a><br />
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br />
4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;<br />
5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;<br />
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void tmGetMsg_Tick(object sender, System.EventArgs e)<br />
7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//群1里的消息<br />
9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string strMsg = QQHooks.GetMsg(txtGroupWinName1.Text);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string str = &quot;&quot;;<br />
11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!string.Empty.Equals(strMsg))<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList msgList = ParseMsg.Parse(strMsg);<br />
15<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach(QQMsg msg in msgList)<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&quot;253822559&quot; == msg.Number.ToString())continue;<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(string.Empty.Equals(msg.Msg.Trim()))<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str =&nbsp;&nbsp;string.Format(&quot;{0}在群1里做了个表情\r\n&quot;,msg.Name,msg.Msg);<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str =&nbsp;&nbsp;string.Format(&quot;{0}在群1里说:\r\n{1}\r\n&quot;,msg.Name,msg.Msg);<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbGroupMsgList1.Items.Add(str);<br />
26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//save msg <br />
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//发送消息<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QQHooks.SendMsg(txtGroupWinName2.Text,str);<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QQHooks.SendMsg(txtGroupWinName3.Text,str);<br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
34&nbsp;&nbsp;}<br />
这里的txtGroupWinName1是让输入qq窗口标题。以前用asm32做程序的时候就觉的微软够BT的，要是每个窗口编译的时候就给限制个GUID多好&mdash;（）&mdash;＊）（（&mdash;<br />
至此大功算是告成了，完美交差。拿着这东东，改天狠狠的宰我师兄几顿. <br />
<br />
（07-01-04）续：<br />
要的人太多了,我还是主动把东西传上来吧，要不然有骗 email地址之嫌<br />
源代码和相关资料下载：/Files/sukyboor/Q.rar<br />
<br />
附，说明：先介绍一下http方法：<br />
1，qq接口.txt<br />
&nbsp;&nbsp; 是我在网络上找的一篇&ldquo;C#编写QQ接口软件--QQ协议篇&rdquo; 里面有QQhttp协议访问的详细的介绍，协议标准是v1.1。但是经过我是没调通,好象是</font><a target="_blank" href="http://tqq.tencent.com:8000/"><font size="3">http://tqq.tencent.com:8000</font></a><font size="3">被封了，你有没有好的运气我就不知道了。tx的<a href='/web/Index.html'>Web</a>qq用的端口是</font><a target="_blank" href="http://<a href='/web/Index.html'>Web</a>qq-proxy.qq.com:8080/"><font size="3">http://<a href='/web/Index.html'>Web</a>qq-proxy.qq.com:8080/</font></a><font size="3">这个就是慢点，用还是能用的。<br />
2,Maxthon_Appin 文件夹下面有2个文件QQTest.txt ，GetQQSession.txt。maxthon有个简易收集面板你可以动态的去调试脚本.用maxthon打开</font><a target="_blank" href="http://<a href='/web/Index.html'>Web</a>qq.qq.com/"><font size="3">http://<a href='/web/Index.html'>Web</a>qq.qq.com</font></a><font size="3">后装入qqtest.txt你会发现访问过程的一举一动都在你的监视之中。Log.txt就是这么来的。GetQQSession.txt操作同上，用于获取一个新的sessionid<br />
3,log.txt是监视</font><a target="_blank" href="http://<a href='/web/Index.html'>Web</a>qq.qq.com/"><font size="3">http://<a href='/web/Index.html'>Web</a>qq.qq.com</font></a><font size="3">的访问过程后得来的.你可以参考qq接口.txt看。不过tx的<a href='/web/Index.html'>Web</a>qq用的是v1.0的接口，但大体上是相似的，相信聪明的你是可以看懂的。<br />
&nbsp;&nbsp;4,<a href='/web/Index.html'>Web</a>qq文件夹下放着</font><a target="_blank" href="http://<a href='/web/Index.html'>Web</a>qq.qq.com/"><font size="3">http://<a href='/web/Index.html'>Web</a>qq.qq.com</font></a><font size="3">被我下到本地的页面。有兴趣的可以去看看里面的脚本，尤其是js\<a href='/web/Index.html'>Web</a>_cmd.js虽然写的比我还烂，但还是值得一看。<br />
5,WQQ文件夹下放着我写的测试页面。不过我家的破电脑调不通。如果你运气好的话，在这个基础上继续干吧。不过别忘记了,到时候把做好的东西发给我一份(sukyboor&middot;163.com)。<br />
好了，下面说说钩子方法<br />
&nbsp;&nbsp;项目在TQQ文件夹下面,注释写的挺详细的，自己看吧。<br />
就提醒4点，<br />
1 是app.config里面的qqnum一定要配置成你的qq号，否则你就等着别人骂你sx吧。<br />
2 主窗口上的几个输入框一定要配置成群聊窗口的标题，否则它啥也干不了<br />
3 别告诉我你还用qq2005<br />
4 消息被转发以后在窗口里是看不到的，得点聊天记录按纽以后才能看的见<br />
<br />
license.txt<br />
&nbsp;&nbsp;里面堆的是一堆套话,有空就瞅2眼.</font></p> <a href="/mypdf/11193.pdf" title="查看 C#写的基于http协议的QQ聊天机器人 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11193.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议的一些说明]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11192.html</link>
			<description>
				<![CDATA[
<h5 style="padding: 8px; line-height: 20px; font-weight: normal;">　　协议由报文头(T)+发送者(T)+接收者(T)+报文类型(T)+报文长度(L)+报文内容组成</h5>
<div id="content">
<div class="guanggao"><span id="contentAdv">
<script type="text/<a href='/Java/Index.html'>Java</a>script">
document.write('<SCRIPT LANGUAGE="<a href='/Java/Index.html'>Java</a>Script" src='+jsurl+'><\/SCRIPT>');
</script>
<script src="http://www.ctocio.com.cn/ttfiles/ccimages/security_pip.js" language="<a href='/Java/Index.html'>Java</a>Script" type="text/<a href='/Java/Index.html'>Java</a>script"></script>
</span></div>
<p>　　协议由报文头(T)+发送者(T)+接收者(T)+报文类型(T)+报文长度(L)+报文内容组成</p>
<p>　　发送者和接收者是系统内的程序种类,OICQ服务器0x01,传真服务器0x02,<a href='/web/Index.html'>Web</a>服务器0x03,打印服务器是0x04,聊天服务器是0x05,OICQ用户是0x0A。 OICQ用户到OICQ服务器的通讯协议 引导符 (0x81+0x0A+0x01)</p>
<p>　　报文类型 报文内容 报文说明</p>
<p>　　0x01 昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区</p>
<p>　　(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)</p>
<p>　　+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T) 新用户注册，身份验证用于当有人</p>
<p>　　要将他加入好友时询问是否允许</p>
<p>　　0x02 服务号(L)+密码(S)+注册方式(T) 老用户注册，方式分为0正常，1隐身</p>
<p>　　0x03 服务号(L)+对方服务号(L)+内容(S) 发送信息到某人</p>
<p>　　0x04 服务号(L)+组号(L)+内容(S) 广播信息，组号=0为全体</p>
<p>　　0x05 服务号(L)+朋友服务号(L) 查看朋友资料</p>
<p>　　0x06 服务号(L)+组名称(S) 增加组</p>
<p>　　0x07 服务号(L)+组编号(T)+组名称(S) 修改组名称</p>
<p>　　0x08 服务号(L)+组编号(T) 删除组</p>
<p>　　0x09 服务号(L)+移动人数(T)+{朋友服务号(L)+目的组号(T)} 移动组成员</p>
<p>　　0x0a 服务号(L)+起始编号(L)+回传个数(T)+查找标志(T) 看谁在线上</p>
<p>　　查找标志 1=向小找 2=向大找</p>
<p>　　0x0b 服务号(L)+<a href='/Tag/716/Index.html'>sql语句</a>(S) 自定义查找</p>
<p>　　0x0c 服务号(L)+朋友服务号(L) 增加好友</p>
<p>　　0x0d 服务号(L)+朋友服务号(L)+加入原因(S) 请求加入好友</p>
<p>　　0x0e 服务号(L)+朋友服务号(L) 删除好友</p>
<p>　　0x10 服务号(L)+显示模式(T) 更改显示方式 1上线2隐藏3免打扰4离线</p>
<p>　　0x11 服务号(L)+监视服务号(L) 监视某人谈话</p>
<p>　　0x12 服务号(L)+昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+</p>
<p>　　国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+</p>
<p>　　电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S)+身份验证(T) 更改用户基本信息</p>
<p>　　0x13 服务号(L)+朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件</p>
<p>　　0x14 服务号(L)+朋友服务号(L)+允许/拒绝 是否允许发送文件</p>
<p>　　0x15 服务号(L)+朋友服务号(L)+文件内容(B) 发送文件</p>
<p>　　0x16 服务号(L) 连接测试报文</p>
<p>　　0x17 服务号(L)+朋友服务号(L)+同意标志(T) 应答对方请求加入好友</p>
<p>　　0=拒绝</p>
<p>　　1=同意 OICQ服务器到OICQ的通讯协议</p>
<p>　　报文类型 报文内容 报文说明</p>
<p>　　0x01 成功/失败(T)+服务号(L) 新用户注册结果返回</p>
<p>　　0x02 成功/失败(T)+组个数(T)+{组名称(S)+组编号(T)+朋友个数(T)+{朋友服务号</p>
<p>　　(L)+肖像编号(T)+朋友状态(T)+朋友昵称(S)] 老用户注册结果返回</p>
<p>　　朋友状态</p>
<p>　　1=上线=2隐藏=3免打扰4离线</p>
<p>　　0x03 标志(T) + 朋友服务号(L)+信息(S)+信息类型(T) 标志 1=系统 2=用户</p>
<p>　　发送消息，服务号=0是系统消息</p>
<p>　　1=用户某某已经把你加为好友</p>
<p>　　2=用户某某请求你通过身份验证</p>
<p>　　3=用户某某同意了你的验证要求</p>
<p>　　4=用户某某拒绝了你的验证请求</p>
<p>　　0x04 成功/失败(T)+朋友服务号(L)+昵称(S)+肖像(M)+性别(T)+年龄(T)+真实姓名</p>
<p>　　(S)+国家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业</p>
<p>　　(T)+电话(S)+寻呼(S)+电邮(S)+爱好(S)+说明(S) 朋友信息回送</p>
<p>　　0x05 成功/失败(T)+组编号(T)+组名称(S) 增加组结果回送 1/0</p>
<p>　　0x06 成功/失败(T)+组编号(T)+组名称(S) 修改组名称结果回送1/0</p>
<p>　　0x07 成功/失败(T)+组编号(T) 删除组结果回送1/0</p>
<p>　　0x08 成功/失败(T) 移动组成员结果回送1/0</p>
<p>　　0x09 成功/失败(T)+在线个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)}</p>
<p>　　查找在线人员结果回送</p>
<p>　　0x0a 成功/失败(T)+找到个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)}</p>
<p>　　自定义查找结果回送(最多50)</p>
<p>　　0x0b 标志(T)+朋友服务号(L) 增加好友结果回送标志</p>
<p>　　0=<a href='/DataBase/Index.html'>数据库</a>失败</p>
<p>　　=1成功</p>
<p>　　=2需要身份验证</p>
<p>　　=3对方不允许加入</p>
<p>　　=4需要身份验证且不在线</p>
<p>　　0x0c 朋友服务号(L)+昵称(S)+肖像号(M)+朋友状态(T) 给在线用户增加好友</p>
<p>　　0x0e 成功/失败(T)+朋友服务号(L) 删除好友结果回送</p>
<p>　　0x10 服务号(L)+显示模式(T) 显示模式回送 =1上线=2隐藏=3免打扰4离线</p>
<p>　　0x11 成功/失败 更改用户基本信息结果回送</p>
<p>　　0x12 朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件</p>
<p>　　0x13 朋友服务号(L)+允许/拒绝 是否允许发送文件 1允许 0拒绝</p>
<p>　　0x14 朋友服务号(L)+文件内容(B) 发送文件</p>
<p>　　0x15 朋友服务号(L)+当前状态(T) 朋友状态回送(系统发送)=1上线=2隐藏=3免打扰4离线</p>
<p>　　0x16 服务号(L) 连接测试</p>
</div> <a href="/mypdf/11192.pdf" title="查看 QQ协议的一些说明 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11192.html</guid>
		</item>
		<item>
			<title><![CDATA[自己开发的一款QQ协议调试器 QQDebugger]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11191.html</link>
			<description>
				<![CDATA[
<p>点这里下载 请求协议分析工具 <a href="/UploadFiles/<a href='/crazycoder/Index.html'>CrazyCoder</a>_CN_QQDebugger.zip"><a href='/crazycoder/Index.html'>CrazyCoder</a>_CN_QQDebugger.zip</a></p>
<p><br />
QQ协议老变，为了分析协议，单用抓包工具还是不够的，还是得需要很好的调试工具。在网上找了几个调试工具，易用性均欠佳，不得已自己开发了一个 QQDebugger，不敢专美，特意发布出来。<br />
<br />
QQDebugger 在功能上同 Red_angelX（http://blog.csdn.net/Red_angelX/）的 QQ_Debugger（http://blog.csdn.net/Red_angelX/archive/2006/09/14 /1221914.aspx）样，在易用性上有很大的改进，非常贴和 Ethereal 抓包结果，运行需要 .Net Framework 2.0。<br />
<br />
下面以一个简单的QQ协议包分析为例，演示 QQDebugger 的使用：<br />
<br />
(1) 抓包<br />
<br />
<img height="546" width="626" src="/<a href='/web/Index.html'>Web</a>Files/20089/0103b401-de66-4e61-971f-d37634cacd50.jpg" alt="" /><br />
&nbsp;</p>
<p class="MsoNormal"><span style="font-family: 宋体;">（</span><span lang="EN-US">2</span><span style="font-family: 宋体;">）把欲分析的包</span> <span style="font-family: 宋体;">复制到</span> <span style="font-family: 宋体;">任意一个文本编辑器中，本例中的包如下：</span></p>
<p><br />
<img src="/<a href='/web/Index.html'>Web</a>Files/20089/3141df73-5dd1-4260-a52b-45989126235f.jpg" alt="" /><br />
<br />
了解QQ协议的知道，这里红线部分是 这个包中 TEA加密的密钥，绿线部分是 TEA 加密后的密文。<br />
<br />
要知道明文，只需要从文本编辑器中，将密钥和密文分别复制到 QQDebugger 的响应对话框中（不需要清理文本格式！ QQDebugger 会自动清理文本）：<br />
<br />
<img src="/<a href='/web/Index.html'>Web</a>Files/20089/e88dfbfd-1384-4afd-b178-bc71b42d3342.jpg" alt="" /><br />
<br />
（3）点解密，可得到明文，这时候密钥和密文也自动本清理成整齐的字符串：<br />
<br />
<img src="/<a href='/web/Index.html'>Web</a>Files/20089/325781d7-7cd3-48fe-949d-56e63a405757.jpg" alt="" /><br />
<br />
说明: <br />
<br />
(1) QQDebugger 中使用了 Red_angelX 撰写的C# 版 加解密算法(http://blog.csdn.net/Red_angelX/archive/2006/09.aspx)。<br />
(2) 欲了解QQ协议，可看 lumaqq 的协议文档（google 吧），Red_angelX 的博客上有对 QQ2006 Beta3 的协议登录部分的分析。<a href="http://files.cnblogs.com/xiaotie/QQDebugger.zip"><br />
</a></p>
<p>转自博客园xiaotie的博客 傲博知识库</p>
<p>&nbsp;</p> <a href="/mypdf/11191.pdf" title="查看 自己开发的一款QQ协议调试器 QQDebugger 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11191.html</guid>
		</item>
		<item>
			<title><![CDATA[基于HTTP的QQ协议分析以及见解]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11190.html</link>
			<description>
				<![CDATA[
<p>最近为了一个项目对QQ协议进行研究,有些心得,不敢独享,故把其中一项协议--基于HTTP的QQ协议V1.1的不完整成果,拿出来与大家分享一下。<br />
大家说到QQ协议都觉得很神秘，是因为QQ不像MSN或者ICQ协议都已经官方公布了，而QQ的没有公布。研究它的人也不是特别的多，虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim, LumaQQ，但是由于他们是基于二进制Stream的协议过于复杂，大家阅读代码也有一定的难度，再加上网络上解析QQ协议的文章也不是十分多，所以基 于QQ网络协议的应用程序也是寥寥无几的。现在我就把基于HTTP的QQ协议进行一个粗浅的剖析，希望对大家有所帮助。源码部分就用我喜欢的DELPHI 和现在比较流行的C#语言对QQ协议的实现进行具体分析。<br />
1、找寻支持QQ HTTP协议的服务器。<br />
大家也许会被一些假像所迷惑，也许会 认为QQ的HTTP服务器是基于80口进行通信的（如：218.17.209.23:80），其实不然，正真基于HTTP的服务器应该 是：http：//tqq.tencent.com:8000，它是一个通过8000口进行通讯的服务器。<br />
由于QQ的HTTP服务器并不支持HTTP协议中GET方法，它支持POST方法。所以我们要给QQ的HTTP协议传参数，那么就必需要用POST方式才行。<br />
2、C#和DELPHI是实现HTTP的POST方法的通信。<br />
C#：<br />
C# 里System.<a href='/web/Index.html'>Web</a>空间下提供了一个叫做<a href='/web/Index.html'>Web</a>Client的对象，使用此对象就可以使C#直接对服务器发送<a href='/web/Index.html'>Web</a>客户端的请求。那么我们要对服务器 提交POST方法那么就必须使用其UploadData()方法才行。首先把要请求的信息先转换为字节（因为POST提交的是字符的流数据），然后再做为 UploadData()的参数。使用UploadData()进行数据提交，最后返回，POST的回馈信息。如下：<br />
<br />
<a href='/web/Index.html'>Web</a>Client _client = new <a href='/web/Index.html'>Web</a>Client();<br />
string postValues = &quot;VER=1.0&amp;CMD=Query_Stat&amp;SEQ=12321&amp;UIN=29501213&amp;TN=50&amp;UN=0&quot;;<br />
Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues);<br />
Byte[] pageData = _client.UploadData(Host,&quot;POST&quot;,byteArray);<br />
<br />
这样，我们就利用C#进行了一次HTTP的POST方法提交了。<br />
<br />
DELPHI：<br />
Delphi里我们利用一个比较流行的第三方VCL，INDY HTTP（这个组件D6，D7里面自带）进行HTTP通信。使用其的POST方法便可以进行HTTP的POST通信，因为组件比较好用，我就不在其描述具体的过程了。大家可以参考以下代码：<br />
<br />
function Post<a href='/web/Index.html'>Web</a>Page(url,para:String;TimeOut:Integer):String;<br />
var<br />
tmp<a href='/web/Index.html'>Web</a>:TIdHTTP;<br />
retrun:String;<br />
Proxy:String;<br />
i:Integer;<br />
paralist:TStrings;<br />
begin<br />
retrun:='';<br />
try<br />
paralist:=TStringList.Create;<br />
paralist.Text:=_Replacing(para,'&amp;',#13#10);<br />
tmp<a href='/web/Index.html'>Web</a>:=TIdHTTP.Create(nil);<br />
tmp<a href='/web/Index.html'>Web</a>.ReadTimeout:=TimeOut;<br />
for i:=1 to 3 do<br />
begin<br />
try<br />
retrun:=tmp<a href='/web/Index.html'>Web</a>.Post(url,paralist);<br />
except end;<br />
if retrun&lt;&gt;'' then break;<br />
end;<br />
finally<br />
tmp<a href='/web/Index.html'>Web</a>.Disconnect;<br />
FreeAndNil(tmp<a href='/web/Index.html'>Web</a>);<br />
FreeAndNil(paralist);<br />
end;<br />
<br />
Result:=retrun;<br />
end;<br />
<br />
值在传入、返回时，其是基于UTF-8进行的，C#显示中文是很常，而DELPHI就要进行UTF-8的转换了。大家可通过Utf8ToAnsi()、AnsiToUtf8()进行转换。（编码转换是C#的优越性之一）<br />
<br />
3、实现QQ的用户登录。<br />
在QQ通信中用户必需要登录后才可以进行互相发送信息等。QQ的登录是很关键的，大家所看到的用户在线，并不是用户的QQ一直连接着服务器，而是定时发送消信给服务器，证明自己还连着线，如果超出时间QQ就认为用户已经掉线了。<br />
在登录协议中，QQ的密码是用标准的<a href='/Tag/16228/Index.html'>md5</a>来进行加密，DELPHI的用户只需要下个<a href='/Tag/16228/Index.html'>md5</a>加密模块就可以了，而C#自已带有，但是直接用不了，必需进行处理后，才能使其变成标准的<a href='/Tag/16228/Index.html'>md5</a>，处理代码如下：<br />
<br />
public static string <a href='/Tag/16228/Index.html'>md5</a>(string toCryString)<br />
{<br />
<a href='/Tag/16228/Index.html'>md5</a>CryptoServiceProvider hash<a href='/Tag/16228/Index.html'>md5</a>;<br />
hash<a href='/Tag/16228/Index.html'>md5</a> = new <a href='/Tag/16228/Index.html'>md5</a>CryptoServiceProvider();<br />
return BitConverter.ToString(hash<a href='/Tag/16228/Index.html'>md5</a>.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace(&quot;-&quot;,&quot;&quot;).ToLower();//asp 是小写,把所有字符变小写<br />
} <br />
<br />
了解QQ是如何对用户密码加密后，那么我们就开始真正，解析QQ的HTTP登录协议了,我们把协议当传POST的参数传给服务器，而服务器则回馈相应的信息给客户端：<br />
传入协议：<br />
VER=1.1&amp;CMD=Login&amp;SEQ=&amp;UIN=&amp;PS=&amp;M5=1&amp;LC=9326B87B234E7235<br />
<br />
VER 是用来说明QQ协议的版本，CMD是说明协议的命令，Login就是指QQ的登录了，SEQ是他的为了防止重复发送而设定的一个标记，一般我们取当前时间 数值的一段放入即可。（C#：DateTime.Now.Ticks.ToString().Substring(7,7) DELPHI：CopyStr(inttostr(GetTickCount()),1,5)），UIN是说明你当前要登录的用户QQ号，PS，是<a href='/Tag/16228/Index.html'>md5</a> 加密过后的密码的值<a href='/crazycoder/Index.html'>CrazyCoder</a> 傲博知识库。<br />
<br />
返回协议：<br />
<br />
VER=1.1&amp;CMD=Login&amp;SEQ=11281&amp;UIN=&amp;RES=0&amp;RS=0&amp;HI=60&amp;LI=300（成功）<br />
<br />
RES为0表示成功返回，RS为0表示登录成功。<br />
<br />
VER=1.1&amp;CMD=Login&amp;SEQ=11422&amp;UIN=315103947&amp;RES=0&amp;RS=1&amp;RA=登录失败<br />
<br />
RS为1表示登录失败，那么就会出现提示信息RA说明原因</p>
<p><br />
4、获得QQ名单。<br />
如果您加了您的好友，那么您的好友就会放入你的QQ的好友名单里面，那么我们要得到QQ名单就必需给QQ服务器发送得到好友名单的协议（我就不从复已知的参数了）：<br />
<br />
VER=1.1&amp;CMD=List&amp;SEQ=&amp;UIN=&amp;TN=160&amp;UN=0 <br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=LIST&amp;SEQ=43661&amp;UIN=29501213&amp;RES=0&amp;FN=1&amp;SN=24&amp;UN=561256,1943497,....<br />
<br />
UN后面则是您好友的QQ号码，每个号码都由,进行分开。那么我们只需要得到UN后面的代码，把它列表化就OK了。C#可以用string.Split(',')把值放入列表进行处理，而DELPHI可以使用Split()把数值放入TStrings里进行处理。<br />
<br />
5、获得QQ好友在线名单<br />
获得QQ好友在线名单，跟获得好友名单差不多，唯一不同的是用的命令不同用的是Query_Stat，协议如下：<br />
<br />
VER=1.1&amp;CMD=Query_Stat&amp;SEQ=&amp;UIN=&amp;TN=50&amp;UN=0 <br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=QUERY_STAT&amp;SEQ=-1&amp;UIN=29501213&amp;RES=0&amp;FC=141,270,270,&amp;FN=1&amp;SN=3&amp;ST=10,10,10,&amp;UN=12327207,24259132,29501213,&amp;NK= □,微程,鶹鸑,&amp; <br />
<br />
FC为QQ头像的的ID，如的头像ID为270，那么其头使用的图片为91.bmp,其算法为 ID/3+1。ST为QQ用户的状态，10为上线，20为离线，30为忙碌。UN为在线用户的QQ号，NK为在线用户的QQ昵称。ST，UN，NK，每个 逗号隔开的数据相互对应。在得到消息后如果用的是DELPHI语言，那么要用Utf8ToAnsi()进行转换，不然会出现乱码。<br />
<br />
6、得到QQ用户的信息。<br />
如果要看到QQ用户的真实名称，MAIL，年龄，个人说明等信息，那么我们必需要向服务器发送得到好友信息的信息：<br />
<br />
VER=1.1&amp;CMD=GetInfo&amp;SEQ=&amp;UIN=&amp;LV=2&amp;UN=<br />
<br />
UN为要查看用户信息的QQ号。<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp; amp;CMD=GETINFO&amp;SEQ=12707&amp;UIN=415103947&amp;RES=0&amp;AD=云南昆明&amp; amp;AG=0&amp;EM=Microprogramer@hotmail.com&amp;FC=270&amp;HP=msger.org(建 设中...)&amp;JB=程序员&amp;LV=2&amp;PC=650000&amp;PH=0871-6466529&amp;PR=网络为 媒%252c关系为本%252c信息为财%252c客户为主.%0d%0a&amp;PV=云南省&amp;RN=刘X&amp;SC=社会大学&amp; amp;SX=0&amp;UN=24259132&amp;NK=微程<br />
<br />
AD用户的联系地址，AG为用户年龄，EM为用户MAIL，FC 为用户头像，HP为用户网站，JB为用户职业，PC为用户邮编，PH为用户联系电话，PR为用户简介，PV为用户所以的省，RN为用户真实名称，SC为用 户毕业院校，SX为用户性别，UN为用户QQ号，NK为用户QQ昵称。在得到消息后如果用的是DELPHI语言，那么要用Utf8ToAnsi()进行转 换，不然会出现乱码</p>
<p>7、增加QQ好友。<br />
想要新增好友，就要发送AddToList命令给服务器，具体命令如下：<br />
<br />
VER=1.1&amp;CMD=AddToList&amp;SEQ=&amp;UIN=&amp;UN=<br />
<br />
UN为我们要增加用户的QQ号。<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=AddToList&amp;SEQ=13666&amp;UIN=415103947&amp;RES=0&amp;CD=0&amp;UN=24259132<br />
<br />
CD 为被加QQ的身份验证状态，CD为0表示&ldquo;允许任何人把我列为好友&rdquo;，CD为1表示&ldquo;需要身份证认才能把我列为好友&rdquo;，CD为3表示&ldquo;不允许任何人把我列 为好友&rdquo;。如果CD为0那么信息回馈后，用户就直接加为好友了，如果CD为1，那么还要发送一次回应加为好友的响应。<br />
<br />
8、回应加为好友的响应。<br />
<br />
回应加为好友响应是双方的：1、如果你发送了请求加对方为好友，如果对方需要验证，那么必需发送回应加为好友的响应。2、如果对方发送加为好友请求给你，那么你可以加应加为好友的响应，一是加为好友，一是通过验证，一是拒决加为好友。我们要向服务器发送命令：<br />
<br />
VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=&amp;UIN=&amp;UN=&amp;CD=&amp;RS=<br />
<br />
CD为响应状态，CD为0表示&ldquo;通过验证&rdquo;。CD为1表示&ldquo;拒决加为对方为好友&rdquo;。CD为2表示&ldquo;为请求对方加为好友&rdquo;。RS为你要请求的理由，如果您用的是DELPHI那么RS在发送之间要用AnsiToUtf8()进行转换，不然发送过后，请求理由会变成&ldquo;？&rdquo;。<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=1130&amp;UIN=415103947&amp;RES=0&amp;<br />
<br />
9、删除好友。<br />
<br />
删除好友其实很容易，向服务器发送DelFromList命令则可以删除用户：<br />
<br />
VER=1.1&amp;CMD=DelFromList&amp;SEQ=&amp;UIN=&amp;UN= <br />
<br />
UN为要删除用户的QQ号。<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=DelFromList&amp;SEQ=24514&amp;UIN=415103947&amp;RES=0&amp;<br />
<br />
10、改变用户当前状态。<br />
可以把QQ设置为在线，隐身等状态，我们可以发送Change_Stat给服务器以改变当前状态，具体命令如下：<br />
<br />
VER=1.1&amp;CMD=Change_Stat&amp;SEQ=&amp;UIN=&amp;ST= <br />
<br />
ST为要改变的状态，10为上线，20为离线，30为忙碌。傲博知识库<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=Change_Stat&amp;SEQ=17512&amp;UIN=415103947&amp;RES=0&amp;</p>
<p>11、退出登录<br />
要退出登录，要向服务器发送命令Logout，具体命令如下：<br />
<br />
VER=1.1&amp;CMD=Logout&amp;SEQ=&amp;UIN=<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=LOGOUT&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0<br />
<br />
12、获得好友QQ的消息<br />
<br />
如果要接收好友的消息，要向服务器发送命令GetMsgEx，具体命令如下：<br />
<br />
VER=1.1&amp;CMD=GetMsgEx&amp;SEQ=&amp;UIN= <br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=GETMSGEX&amp;SEQ=56661&amp;UIN=29501213&amp;RES=0&amp;MN=3&amp;MT=99,9,9,&amp;UN=24259132,24259132,24259132,&amp;MG=30 ,asdfasdfasdfasdf ,asdfasdfasdf ,&amp;<br />
<br />
MT表示消息类型，99表示系统消息，9表示用户消息。 UN表示消息发送来源用户，MG表示发送的消息，MG消息可以表示某些特定的系统含意，譬如：当MT为99，MG为30，UN为24259132则表示用 户4259132现在处于忙碌状态，可根据此消息进行好友列表的刷新，提高效率。在得到消息后如果用的是DELPHI语言，那么要用 Utf8ToAnsi()进行转换，不然会出现乱码。<br />
<br />
13、向好友QQ发送消息<br />
<br />
要发送消息给好友，要向服务器发送命令CLTMSG命令，具体命令如下：<br />
<br />
VER=1.1&amp;CMD=CLTMSG&amp;SEQ=&amp;UIN=&amp;UN=&amp;MG= <br />
<br />
UN为消息发送给的用户QQ号码，MG为发送给该用户的消息。如果您用的是DELPHI那么MG在发送之间要用AnsiToUtf8()进行转换，不然发送过后，消息会变成&ldquo;？&rdquo;。<br />
<br />
服务器得到协议后如果成功则返回：<br />
<br />
VER=1.1&amp;CMD=CLTMSG&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0<br />
<br />
好了，以上就是QQ基于HTTP的一个不完全的协议分析，在无源码前提下，在下能力有限，只能够分析这么多了。利用以上协议您就可以实现很多东西，如：QQ机器人，QQ广告系统，即时通讯的整合工具等等。</p>
<p>&nbsp;<!-- End: CommunityServer.Discussions.Controls.PostDisplay.TextPost --><br />
补充：</p>
<p><font style="background-color: rgb(239, 239, 239);">返回的系统消息参数的意义</font></p>
<p><font style="background-color: rgb(239, 239, 239);">20 对方登陆QQ</font></p>
<p><font style="background-color: rgb(239, 239, 239);">30 对方忙碌</font></p>
<p><font style="background-color: rgb(239, 239, 239);">41 对方希望通过验证</font></p> <a href="/mypdf/11190.pdf" title="查看 基于HTTP的QQ协议分析以及见解 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11190.html</guid>
		</item>
		<item>
			<title><![CDATA[基于HTTP的QQ协议代码，Python实现登陆等操作！]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11189.html</link>
			<description>
				<![CDATA[
<font class="f14" id="zoom">
<pre>
转载，很久以前的文章了，
仅供参考，
看到微程朋友分析基于http的QQ协议，于是准备写一个QQ程序。原以为有些包不能用了，后来灰衣人朋友的帮助下，才知道http通讯需要打开一次，关闭一次的。而不能象socket样，一直打开不关闭。

感谢微程和灰衣人朋友的帮助。关于协议大家可以看他的blog

http://spaces.msn.com/members/mprogramer/Blog/cns!1pKnbff3FpJuGZcrsAlNZmZQ!147.entry

本程序为MIT授权

如果需要转载本程序，请保留版权信息&quot;&quot;&quot;

import&nbsp;urllib,httplib,<a href='/Tag/16228/Index.html'>md5</a>,time

class&nbsp;qq:

&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;__init__(self,qq=&quot;&quot;,pwd=&quot;&quot;):

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.pwd=<a href='/Tag/16228/Index.html'>md5</a>.new(pwd).hexdigest()

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=&quot;&quot;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq=qq

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;getdata(self):

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.conn=&nbsp;httplib.HTTPConnection(&quot;tqq.tencent.com:8000&quot;)#这里是tqq.tencent.com的ip地址，也可以直接用域名

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.conn.request(&quot;POST&quot;,&quot;&quot;,&nbsp;self.headers)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response&nbsp;=&nbsp;self.conn.getresponse()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;response.read().decode('utf-8').encode(&quot;cp936&quot;)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.conn.close



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;Login(self):#登陆

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=Login&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;PS=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.pwd+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&amp;M5=1&amp;LC=9326B87B234E7235&quot;)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;Query_Stat(self):#在线好友

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=Query_Stat&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;TN=50&amp;UN=0&quot;)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;List(self):#好友列表

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=List&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;TN=160&amp;UN=0&quot;)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;GetInfo(self,friend=&quot;&quot;):#指定QQ号码的详细内容

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=GetInfo&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;LV=2&amp;UN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()&nbsp;



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;AddToList(self,friend=&quot;&quot;):#增加指定QQ号码为好友

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=AddToList&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;UN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;GetMsg(self):#获取消息

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=GetMsgEx&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;SendMsg(self,friend=&quot;&quot;,msg=&quot;&quot;):#发送消息

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=CLTMSG&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq+&quot;&amp;UN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;friend+&quot;&amp;MG=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg.decode(&quot;cp936&quot;).encode('utf-8'))

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()



&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;Logout(self):#退出登陆

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.headers=(&quot;VER=1.0&amp;CMD=Logout&amp;SEQ=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str(int(time.time()*100)%(10**5))+&quot;&amp;UIN=&quot;+\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.qq)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.getdata()



test=qq('号码','密码')

test.Login()

test.Query_Stat()

test.List()

test.GetInfo('他人QQ号码')

test.AddToList('他人QQ号码')

test.GetMsg()

i=0

while&nbsp;i&lt;1000:

&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;i

&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(0.9)

&nbsp;&nbsp;&nbsp;&nbsp;test.SendMsg('他人QQ号码',&quot;一共有1000条消息，这是第&quot;+str(i)+&quot;条消息&quot;)

&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;=&nbsp;i+1

test.Logout()</pre>
</font> <a href="/mypdf/11189.pdf" title="查看 基于HTTP的QQ协议代码，Python实现登陆等操作！ 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11189.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议开发之最基本的QQ客户端：CQQClient初版]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11188.html</link>
			<description>
				<![CDATA[
<p>到目前为止，我已经介绍了QQProtocol中代码的基本结构：</p>
<br />
<p>CQQUser存储一个QQ用户的所有信息，包括客户指定信息（用户名，密码 等）和服务器返回信息（指在和服务器通讯过程中服务器&ldquo;设置的&rdquo;信息，如各种各样的密钥是在和服务器通讯过程中某些特定步骤由服务器生成并返回的，而还有 些信息如服务器IP和端口则是最初由客户指定，但有可能因为服务器重定向而改变，等等等等）</p>
<br />
<br />
<p>CInPacket和COutPacket是 发送/接收包基类，CBasicInPacket/CBasicOutPacket是QQ基本协议族发送/接收包基 类，CBasicFamilyParser是QQ基本协议族消息管理器，至于要和QQ服务器正常通讯，还要用&ldquo;<a href='/Translate/Index.html'>翻译</a>&rdquo;成QQ服务器的&ldquo;语言&rdquo;&mdash;&mdash;由 CCrypter加密/解密包</p>
<br />
<br />
<p>最后，所有类使用的常量则实现为类QQ的公共静态成员变量</p>
<br />
<br />
<p>而所有这些类都是为 CQQClient类服务的，它是QQProtocol的操作接口（数据接口则是CQQUser）。目前实现的版本主要接口是Login，负责向QQ服务 器登录。由它负责创建一个工作线程，向服务器发包，等待回复，回复的结果调用CQQClient的虚函数，所以对于库的使用者，需要生成一个派生类实现这 些虚函数以处理回复。</p>
<br />
<br />
<p>至此，很多朋友关心的demo也可以实现一个最简单的版本了，目前的demo是个命令行程序，使用UDP方式登录，已经测试成功。</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#000099">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
<p>例子<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/demo/"><u><font color="#000099">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/demo/</font></u></a><br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11188.pdf" title="查看 QQ协议开发之最基本的QQ客户端：CQQClient初版 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11188.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议之开始上线！登录/应答]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11187.html</link>
			<description>
				<![CDATA[
<p>有了请求登录包返回的密钥（CQQUser::m_pbInitKey），就可以开始构造登录包了（这里顺便提一下，登录包里带有QQ最重要的数据&mdash;&mdash;密码，没有登录密钥直接发送密码原文是极不<a href='/Security/Index.html'>安全</a>的，这也是为什么登录包之前还要请求登录/应答过程的原因）。</p>
<br />
<p>登录和登录回复包是用登录密钥加密/解密的</p>
<br />
<p>登录包构造（CLoginPacket::PutBody）和登录回复解析（CLoginReplyPacket::ParseBody）的每一步在源代码中注释都有说明，其中着重注意：</p>
<br />
<p>登录包构造中：没什么好说的，看代码</p>
<br />
<p>登录回复包解析中：</p>
<br />
<p>很 多请况下不会直接登录成功，而是由服务器返回一个登录重定向包（回复码是QQ.QQ_REPLY_LOGIN_REDIRECT），而且不止一次重定向服 务器，所谓重定向即&mdash;&mdash;你向一个QQ服务器发送登录请求，而这个服务器会告诉你另一个QQ服务器地址和端口（不要告诉我你认为腾讯只有一个服务器</p>
<img border="0" align="absmiddle" src="/<a href='/web/Index.html'>Web</a>Files/20089/162beb12-0ed8-4bc2-a842-ffe2930e86b8.gif" alt="" />
<p>），这时你就要向后者重发登录包（但是登录密钥都是一样的）。至于为什么不直接在这个服务器登录，这你就要问腾讯的客服了（取决于服务器的策略）</p>
<br />
<p>如果登录失败，会返回失败消息的字符串</p>
<br />
<p>最后就是登陆成功的消息，登录成功会返回很多重要信息，包括你想到的和没想到的，其中session key（会话密钥）是下一个密钥，你今后发送的大多数消息和接收的大多数消息，都是用这个密钥加密解密的</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#6faf30">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11187.pdf" title="查看 QQ协议之开始上线！登录/应答 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11187.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议之请求登录/应答]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11186.html</link>
			<description>
				<![CDATA[
<p>下面我们开始接触基本协议族具体的发送/接收包，所有的QQ会话都开始于客户端发送基本协议族的请求登录包，这个包的包体是空的，但是在包头因为有请求登录的QQ号（实际上正如前面介绍的，每个基本协议族包的包头都带有QQ号），服务器会知道是哪个QQ号请求登录<br />
QQ服务器返回应答，应答的包体是明码传输的（因为现在还没有密钥），包括回复码，如果允许这个号码登录则回复码是QQ.QQ_REPLY_OK，而且返回一个登录令牌，这个登录令牌是在整个QQ会话过程中的第一个密钥<br />
在QQProtocol中请求登录包是CBasicOutPacket派生类CRequestLoginTokenPacket实现的；而其回复包是CBasicInPacket派生类CRequestLoginTokenReplyPacket实现的。<br />
正如在基本协议族消息管理器中介绍的一样，请注意CBasicFamilyParser代码改变了<br />
而且因为CRequestLoginTokenReplyPacket要直接访问CQQUser的非公开成员，所以CQQUser代码中CRequestLoginTokenReplyPacket被设为CQQUser的友元</p>
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#6faf30">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11186.pdf" title="查看 QQ协议之请求登录/应答 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11186.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ基本协议族消息管理器]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11185.html</link>
			<description>
				<![CDATA[
<p>CBasicFamilyParser处理基本协议族的收发包，它的代码很简单，但作用很重要，它对基本协议族的支持包括：<br />
要发送包的只要传进来 一个CQQUser对象（由这个对象提供要发送包的参数），指定命令号，就会生成一个CBasicOutPacket派生类对象，而这个 CBasicOutPacket派生类对象会送到发送队列中，由发送队列统一调配发送时间，决定需不需要重发，收没收到反馈等等，发送队列以后再详细说 明，这里只提到发送一个包并不是直接做一个二进制buffer，通过socket发出去的，而是生成一个CBasicOutPacket派生类对象，提交 给发送队列，发送队列会对所有CBasicOutPacket派生类对象统一管理，决定每个包的发送时间，重发次数，以及收到Ack删除对应的包等等<br />
收 到的原始数据（二进制数据）通过它转换为CBasicInPacket派生类对象，这个CBasicInPacket派生类对象根据不同的包类型有不同的 用途，比如向上层报告收到的聊天消息，好友状态变更，系统消息，或者是发送包的Ack包，则提交给发送队列，让发送队列删除收到Ack包的发送包（否则这 个包会重发）<br />
CBasicFamilyParser类接口非常简单，对外有CreateOutPacket生成发送包对象和 ParseInPacket生成接收包对象。这个类在每引入一对发送/接收包都会改变，由于目前还没有介绍一个CBasicIn/OutPacket派生 类，所以目前的CreateOutPacket和ParseInPacket都是空的<br />
比如请求登录包/应答包是CRequestLoginTokenPacket/CRequestLoginTokenReplyPacket，那么CreateOutPacket代码中会有<br />
&nbsp;if( sCommand == QQ.QQ_CMD_REQUEST_LOGIN_TOKEN )<br />
&nbsp;{<br />
&nbsp;&nbsp;pBasicInPacket = new CRequestLoginTokenReplyPacket(pQQUser);<br />
&nbsp;}<br />
而ParseInPacket代码中会有<br />
&nbsp;if( sCommand == QQ.QQ_CMD_REQUEST_LOGIN_TOKEN )<br />
&nbsp;{<br />
&nbsp;&nbsp;return new CRequestLoginTokenPacket(pQQUser);<br />
&nbsp;}<br />
依此类推<br />
<br />
代码<a href='/Tag/16222/Index.html'>SVN</a>：<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#6faf30">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
引用请注明出处，谢谢</p> <a href="/mypdf/11185.pdf" title="查看 QQ基本协议族消息管理器 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11185.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ基本协议族接受/发送包基类]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11184.html</link>
			<description>
				<![CDATA[
<p>QQ基本协议族包括大多数QQ系统消息和IM消息，除此之外，还有p2p协议族和04、05等等协议族</p>
<br />
<p>QQ基本协议族的接受包基类是CBasicInPacket，发送包基类是CBasicOutPacket，分别从接受/发送包基类CInPacket和COutPacket派生而来</p>
<br />
<p>CBasicOutPacket 把COutPacket的m_bHeader置为QQ.QQ_HEADER_BASIC_FAMILY，实现了COutPacket的纯虚函数 PutHeader和PutTail；CBasicInPacket实现了CInPacket的纯虚函数ParseHeader和ParseTail。也 就是说基本协议族的包头和包尾有相同的结构，可以看一下接本协议族的包头结构和包尾结构</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#000099">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a> <br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11184.pdf" title="查看 QQ基本协议族接受/发送包基类 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11184.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议的接收/发送包基类]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11183.html</link>
			<description>
				<![CDATA[
<p>接收包基类CInPacket，发送包基类COutPacket</p>
<br />
<p>QQ协议中，不管是接收包还是发送包，在应用层都分为三个部分：</p>
<br />
<p>包头，包括协议类型，源QQ版本号，命令号，和包序列号，发送包还有一个需要/不需要ack标志</p>
<br />
<p>包体和包尾，其中包体是需要加密解密的部分，以后再介绍</p>
<br />
<p>值得注意的是，QQ号码和密码等等都是在包体即需要加密解密的部分中，但包头中包含的东西非常重要，它包括：</p>
<br />
<br />
<p>QQ协议类型，如QQ基本协议族用的是QQ::QQ_HEADER_BASIC_FAMILY(CInPacket/COutPacket的m_bHeader)</p>
<br />
<p>源 QQ版本号，在发IM包（即和其它QQ号通讯）中，在包体也会设置一次，但和QQ系统通讯时，这个源QQ版本号就是这个协议库使用的版本号，现在是 QQ::QQ_CLIENT_VERSION_0E1B，即QQ2005的版本号(CInPacket/COutPacket的m_sSource)</p>
<br />
<p>命令号，这个就很多了，每个CInPacket/COutPacket派生类会设置这个值(CInPacket/COutPacket的m_sCommand)</p>
<br />
<p>包序列号，QQ用它来防止丢包，这个只是发IM包时用到，包序列过程以后介绍(CInPacket/COutPacket的m_sSequence)</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#6faf30">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11183.pdf" title="查看 QQ协议的接收/发送包基类 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11183.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ加密,CCrypter类和QQ消息的加密解密]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11182.html</link>
			<description>
				<![CDATA[
<p>CCrypter类被实现为对QQ消息的加密解密，提供两个公共函数Decrypt和Encrypt。QQ消息的加密算法是一个16次的迭代过程，并且是 反馈的，每一个加密单元是8字节，输出也是8字节，密钥是16字节。密钥在整个消息交互过程中会不同，以后会详细介绍，这里先提一下，有密码密钥，初始密 钥和会话密钥，但是加密算法都是一样的。关于算法，代码上有详尽说明</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/"><u><font color="#6faf30">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</font></u></a><br />
<p>引用请注明出处，谢谢</p> <a href="/mypdf/11182.pdf" title="查看 QQ加密,CCrypter类和QQ消息的加密解密 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11182.html</guid>
		</item>
		<item>
			<title><![CDATA[一个开源QQ协议库QQProtocol]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11181.html</link>
			<description>
				<![CDATA[
<p>基于QQ协议的资料网上有很多了，lumaqq是非常著名的<a href='/Java/Index.html'>Java</a>实现的QQ客户端，本QQ协议库也是基于这些资料和少量抓包分析包后实现的。本协议库是基于QQ2005协议，全VC6实现</p>
<br />
<p>先贴出来QQ协议常量，基本上就是lumaqq完全移植的啦，所有协议常量都实现为类QQ的公共静态成员，给协议库中其它类使用，这么做完全是移植起来方便</p>
<br />
<p>class QQ</p>
<br />
<p>{</p>
<br />
<p>public:</p>
<br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...</p>
<br />
<p>};</p>
<br />
<p>CQQUser类：一个QQ用户的封装，如果一个QQ号码要登录，先要生成一个CQQUser对象，并进行设置</p>
<br />
<p>主要函数：</p>
<br />
<p>构造函数CQQUser&nbsp;构造一个CQQUser对象时指定QQ号码和密码</p>
<br />
<p>SetServerIP&nbsp;设置处理这个QQ用户的服务器，如sz.tencent.com</p>
<br />
<p>SetServerPort&nbsp;端口，sz.tencent.com的端口是8000</p>
<br />
<p>SetHiddenLogin&nbsp;(是否)隐身登录</p>
<br />
<br />
<p>代码<a href='/Tag/16222/Index.html'>SVN</a>：</p>
<a href="https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/">https://vcye23.<a href='/Tag/16222/Index.html'>SVN</a>.sourceforge.net/<a href='/Tag/16222/Index.html'>SVN</a>root/vcye23/qqprotocol/</a> <a href="/mypdf/11181.pdf" title="查看 一个开源QQ协议库QQProtocol 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11181.html</guid>
		</item>
		<item>
			<title><![CDATA[QQ协议概述]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11180.html</link>
			<description>
				<![CDATA[
<p>QQ的版本：</p>
<p>QQ的版本升级比较频繁，而且与多数的软件不同的是，它客户端的升级往往伴随着协议相应的改变。</p>
<p>目前，对研究QQ协议版本比较重要的是：</p>
<p>QQ2000c 。它对应的客户端协议版本是08xx，目前对这个版本的研究比较多。</p>
<p>QQ2003 (0808) 这是腾讯最新公布的QQ版本，目前发现它对应的客户端协议版本是0A 1D。目前对这个版本的研究才刚刚开始，此版本对协议做了比较大的改动。</p>
<p><br />
协议类型：</p>
<p>我们尝试把QQ的协议进行分类：</p>
<p>文字聊天协议族（TCPF, Text Chatting Protocol Family)：它主要支持与其它QQ客户端进行文字聊天。TCPF是建立在UDP协议之上。UDP数据包中的第一个字符02为这个协议族的标识。 TCPF的服务器使用8000号端口，腾讯的QQ客户端软件一般从4000号端口开始尝试使用，但实际上，对客户端使用的端口号并没有限制。目前的研究集 中在TCPF上。</p>
<p>其它未知可能存在的协议族：</p>
<p>我们观察到QQ除了与TCPF服务器通信以外，还有与其它的服务器使用UDP进行通信。目前我们观察到的服务器为 218.17.217.111 : 8000。客户端使用与TCPF不同的端口。目前观察到的从客户端发出的包以06开头，而服务器返回的包则以01开头。目前其具体作用未知。我们注意到一 个有趣的现象是，如果选择离线后重新上线，那么在发出登录包之前，这个通讯已经开始。我们暂时把它命名为数据传输协议族（DTPF，Data Transfer Protocol Family）。最新的研究发现，它传递的是QQ Show的图片数据。</p>
<p>语音、视频聊天：目前还没有开始分析，尚未知道是使用UDP还是TCP协议。</p>
<p>聊天室：没有分析，应该是TCP协议。</p>
<p>随着对这些协议分析的开始，我们会给它们更精细的划分和恰当的命名。</p>
<p><br />
TCPF:</p>
<p>TCPF是建立在UDP协议上的协议族，主要支持文字聊天功能。TCPF是以请求－响应模式工作的。也就是说，客户端发出一个请求，服务器端会给出 一个相应的响应；服务器向客户端发送信息，客户端也会给服务器相应的响应。请求和响应通过相同的序列号来进行配对（请求代码也应该相同）。而且每种请求的 发起方都是相同的。目前，已知的请求包括：</p>
<p>0x0001&nbsp; 注销登录<br />
0x0002&nbsp; 心跳信息<br />
0x0004&nbsp; 更新用户信息<br />
0x0005&nbsp; 搜索用户<br />
0x0006&nbsp; 获取用户信息<br />
0x0009&nbsp; 不需认证方式添加好友<br />
0x000a&nbsp; 删除好友<br />
0x000b&nbsp; 需要认证的方式添加好友<br />
0x000d&nbsp; 设置隐身、示忙等状态<br />
0x0012&nbsp; 确认收到系统消息<br />
0x0016&nbsp; 发送消息<br />
0x0017&nbsp; 收到消息（服务器发起）<br />
0x001a&nbsp; 未知作用。<br />
0x001c&nbsp; 在对方好友列表上删除自己<br />
0x001d&nbsp; 未知作用。<br />
0x0022&nbsp; 登录<br />
0x0026&nbsp; 获取好友清单<br />
0x0027&nbsp; 获取在线好友<br />
0x0030&nbsp; 群操作指令<br />
0x0080&nbsp; 收到系统消息（服务器发起）<br />
0x0081&nbsp; 收到好友状态改变消息（服务器发起）</p> <a href="/mypdf/11180.pdf" title="查看 QQ协议概述 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11180.html</guid>
		</item>
		<item>
			<title><![CDATA[qq连连看助手,使用C#编写QQ连连看助手]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11171.html</link>
			<description>
				<![CDATA[
<p>这几天疯狂代码研究QQ连连看，不知道别人是不是都用了外挂，速度好快，自己手动实在是跟不上。上网下载了一流的外挂，可惜要注册  干脆自己动手写个吧。。。</p>
<p>道理很简单的，如下：<br />
<br />
通过FindWindow 获得QQ连连看的窗口handle，再捕捉QQ连连看的窗口，然后分释每个格的颜色，判断数据，然后存在一个two dimensional array里。这样程序就有了一份QQ连连看的数据了。<br />
<br />
数据都有了，接下来就要找出两点之间是否能连得通。。这个算法也简单。先判断是否两点之间的位置，如果直线则只有一种连接的可能，比如两点的X相同，那么只能是上下的连接等。。<br />
<br />
路茎的代码如下<br />
程序代码<br />
using System;<br />
using System.Drawing;<br />
using System.Windows.Forms;<br />
<br />
namespace LianLianKan<br />
{<br />
/// &lt;summary&gt;<br />
/// Summary description for FindPath.<br />
/// This class is used to find a existing path of two point.<br />
/// Author: DX,<br />
/// email: <a href='/web/Index.html'>Web</a>master@51home.org<br />
/// &lt;/summary&gt;<br />
public class FindPath<br />
{<br />
public FindPath()<br />
{<br />
}<br />
<br />
#region GetTop() GetBottom, GetLeft, GetRight<br />
private int GetTop(int [,] map, Point p)<br />
{<br />
if(p.X &lt;= 0)<br />
return 0;<br />
else<br />
{<br />
for(int i=p.X-1; i&gt;=0; i--)<br />
if(map[i,p.Y] != 0)<br />
return (i+1);<br />
return 0;<br />
}<br />
}<br />
private int GetBottom(int [,] map, Point p)<br />
{<br />
int maxLen = map.GetLength(0);<br />
if(p.X &gt;= maxLen )<br />
return maxLen-1;<br />
else<br />
{<br />
for(int i=p.X+1; i&lt;maxLen; i++)<br />
if( map[i, p.Y] != 0)<br />
return (i-1);<br />
return maxLen-1;<br />
}<br />
}<br />
private int GetLeft(int [,] map, Point p)<br />
{<br />
if(p.Y &lt;= 0)<br />
return 0;<br />
else<br />
{<br />
for(int i = p.Y-1; i&gt;=0; i--)<br />
if( map[p.X, i] != 0)<br />
return (i+1);<br />
return 0;<br />
}<br />
}<br />
private int GetRight(int [,] map, Point p)<br />
{<br />
int maxLen = map.GetLength(1);<br />
if(p.Y &gt;= maxLen)<br />
return maxLen-1;<br />
else<br />
{<br />
for(int i=p.Y+1; i&lt;maxLen; i++)<br />
if(map[p.X, i] != 0)<br />
return (i-1);<br />
return maxLen-1;<br />
}<br />
}<br />
#endregion<br />
<br />
private bool CheckHorizontalPath(int [,] map, Rectangle r)<br />
{<br />
bool check;<br />
for(int i= r.Y; i&lt;= r.Y + r.Height; i++)<br />
{<br />
check = true;<br />
for(int j=r.X + 1; j&lt; r.X + r.Width; j++)<br />
if( map[i,j] != 0 )<br />
{<br />
check = false;<br />
break;<br />
}<br />
<br />
if(check)<br />
{<br />
// MessageBox.Show(string.Format(&quot;Rectangle x:{0}, y:{1}, Width:{2}, Height:{3}&quot;,r.X,r.Y,r.Width,r.Height));<br />
return true;<br />
}<br />
}<br />
return false;<br />
}<br />
<br />
private bool CheckVerticalPath(int [,] map, Rectangle r)<br />
{<br />
bool check;<br />
for(int i = r.X; i&lt;= r.X + r.Width; i++)<br />
{<br />
check = true;<br />
for(int j = r.Y + 1; j &lt; r.Y + r.Height; j++)<br />
if(map[j,i] != 0)<br />
{<br />
check = false;<br />
break;<br />
}<br />
<br />
if(check)<br />
{<br />
// MessageBox.Show(string.Format(&quot;Rectangle x:{0}, y:{1}, Width:{2}, Height:{3}&quot;,r.X,r.Y,r.Width,r.Height)); 傲博知识库<br />
return true;<br />
}<br />
}<br />
return false;<br />
}<br />
<br />
private bool HorizontalConnection(int [,] map, Point p1,Point p2)<br />
{<br />
int upper,lower;<br />
int top1,top2,bottom1,bottom2;<br />
<br />
top1 = GetTop(map,p1);<br />
bottom1 = GetBottom(map, p1);<br />
<br />
top2 = GetTop(map,p2);<br />
bottom2 = GetBottom(map, p2);<br />
<br />
upper = top1 &gt; top2 ? top1 : top2;<br />
lower = bottom1 &lt; bottom2 ? bottom1 : bottom2;<br />
<br />
if(upper &gt; lower)<br />
return false;<br />
else<br />
{<br />
int x = p1.Y &lt; p2.Y ? p1.Y : p2.Y;<br />
Rectangle r = new Rectangle(x, upper, Math.Abs(p2.Y - p1.Y), lower - upper);<br />
<br />
return CheckHorizontalPath(map,r);<br />
}<br />
}<br />
private bool VerticalConnection(int [,] map, Point p1, Point p2)<br />
{<br />
int left, right;<br />
int left1, left2, right1, right2;<br />
<br />
left1 = GetLeft(map, p1);<br />
right1 = GetRight(map, p1);<br />
left2 = GetLeft(map,p2);<br />
right2 = GetRight(map, p2);<br />
<br />
left = left1 &gt; left2 ? left1 : left2;<br />
right = right1 &lt; right2 ? right1 : right2;<br />
<br />
if(left &gt; right)<br />
return false;<br />
else<br />
{<br />
int y = p1.X &lt; p2.X ? p1.X : p2.X;<br />
Rectangle r = new Rectangle(left, y, right - left, Math.Abs(p1.X - p2.X));<br />
<br />
return CheckVerticalPath(map, r);<br />
}<br />
}<br />
public bool IsThereAPath(int [,] map, Point p1, Point p2)<br />
{<br />
if(p1.X == p2.X) // if two block is Vertical then only check vertical connection<br />
return HorizontalConnection(map, p1, p2); <br />
else if(p1.Y == p2.Y) // if two block on is horizontal, then only check for horizontal connection<br />
return VerticalConnection(map, p1, p2); <br />
else if( HorizontalConnection(map, p1, p2) ) // otherwise check for both<br />
return true;<br />
else<br />
return VerticalConnection(map, p1, p2);<br />
}<br />
}<br />
}</p> <a href="/mypdf/11171.pdf" title="查看 qq连连看助手,使用C#编写QQ连连看助手 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11171.html</guid>
		</item>
		<item>
			<title><![CDATA[qq系列之c#编写QQ群发器]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11168.html</link>
			<description>
				<![CDATA[
<p>使用C#实现qq群发器的方法</p>
<p>1、窗体引用两个timer控件，来控循环发送时间 <br />
<br />
2、调试环境 vs2005.net <br />
<br />
程序代码<br />
using System; <br />
using System.Collections.Generic; <br />
using System.ComponentModel; <br />
using System.Data; <br />
using System.Drawing; <br />
using System.Text; <br />
using System.Windows.Forms; <br />
using System.Runtime.InteropServices; <br />
using System.Diagnostics; <br />
<br />
namespace <a href='/crazycoder/Index.html'>CrazyCoder</a>.QQ.QQSendMessage <br />
{ <br />
public partial class QQSendMessage : Form <br />
{ <br />
[DllImport( &quot;user32.dll &quot;)] <br />
static extern IntPtr FindWindow(string lpClassName, string lpWindowName); <br />
[DllImport( &quot;user32.dll &quot;)] <br />
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem); <br />
[DllImport( &quot;user32.dll &quot;, SetLastError = true)] <br />
public static extern IntPtr FindWindowEx(IntPtr parentHandle, int childAfter, string className, int windowTitle); <br />
[DllImport( &quot;user32.dll &quot;, EntryPoint = &quot;SendMessage &quot;)] <br />
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam); <br />
[DllImport( &quot;kernel32.dll &quot;, CharSet = CharSet.Auto)] <br />
public static extern IntPtr GetModuleHandle(string lpModuleName); <br />
<br />
IntPtr hwndQQ; <br />
IntPtr hwnd1; <br />
IntPtr hwnd2; <br />
IntPtr hwnd3; <br />
IntPtr hwnd4; <br />
<br />
public QQSendMessage() <br />
{ <br />
InitializeComponent(); <br />
} <br />
<br />
** void MySendMessage() <br />
{ <br />
string machinename = System.Environment.MachineName;//获得计算机名 <br />
Process[] processlist = Process.GetProcesses(machinename);//得到所有进程 <br />
foreach (Process p in processlist)//列举每个进程 <br />
{ <br />
if (p.MainWindowTitle != &quot; &quot;)//标题是否为空，不为空执行下面代码 <br />
{ <br />
if (p.MainWindowTitle.ToString().Substring(0, 1) == &quot;与 &quot;)//查看窗口标题第一个字是否是&ldquo;与&rdquo;。如果是的，说明是QQ窗口 <br />
{ <br />
hwndQQ = FindWindow( &quot;#32770 &quot;, p.MainWindowTitle.ToString()); <br />
hwnd1 = GetDlgItem(hwndQQ, 0); <br />
hwnd2 = GetDlgItem(hwnd1, 0); <br />
hwnd3 = GetDlgItem(hwnd2, 894); <br />
SendMessage(hwnd3, 194, 0, this.txtInput.Text);//向QQ输入框粘贴字符，this.textBox1.Text是要发送的文字信息 <br />
hwnd4 = GetDlgItem(hwnd1, 1); <br />
SendMessage(hwnd4, 245, 0, Convert.ToString(0)); <br />
} <br />
} <br />
} <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 单个用户发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnSend_Click(object sender, EventArgs e) <br />
{ <br />
MySendMessage();//发送信息,向单个用户发送。 <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 循环发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnSSend_Click(object sender, EventArgs e) <br />
{ <br />
this.Qtimer.Enabled = true; <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 停止发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnSStop_Click(object sender, EventArgs e) <br />
{ <br />
this.Qtimer.Enabled = false; <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 计时器开始发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void Qtimer_Tick(object sender, EventArgs e) <br />
{ <br />
this.MySendMessage(); <br />
} <br />
<br />
** void QunSendMessage()//针对群的消息发送过程 <br />
{ <br />
string machinename = System.Environment.MachineName; <br />
Process[] processlist = Process.GetProcesses(machinename); <br />
foreach (Process p in processlist) <br />
{ <br />
if (p.MainWindowTitle != &quot; &quot;) <br />
{ <br />
if (p.MainWindowTitle.ToString().Substring(p.MainWindowTitle.Length - 1, 1) == &quot;群 &quot;) <br />
{ <br />
hwndQQ = FindWindow( &quot;#32770 &quot;, p.MainWindowTitle.ToString()); <br />
hwnd1 = GetDlgItem(hwndQQ, 0); <br />
hwnd2 = GetDlgItem(hwnd1, 0); <br />
hwnd3 = GetDlgItem(hwnd2, 894); <br />
SendMessage(hwnd3, 194, 0, this.txtGInput.Text);//向QQ输入框粘贴字符 <br />
hwnd4 = GetDlgItem(hwnd1, 1); <br />
SendMessage(hwnd4, 245, 0, Convert.ToString(0)); <br />
} <br />
} <br />
} <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 向群组发消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnGXSend_Click(object sender, EventArgs e) <br />
{ <br />
this.QunSendMessage();//向群发送单条信息 <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 循环向群组发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnGSend_Click(object sender, EventArgs e) <br />
{ <br />
this.QGtimer.Enabled = true; <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 停止向群组发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnGStop_Click(object sender, EventArgs e) <br />
{ <br />
this.QGtimer.Enabled = false; <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 计时器发送消息 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void QGtimer_Tick(object sender, EventArgs e) <br />
{ <br />
this.QunSendMessage();//连续发送信息，多少秒发送一次，自己设定。 <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 利用tencent协议，打开临时对话框&nbsp; <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void btnQQ_Click(object sender, EventArgs e) <br />
{ <br />
string s = &quot;tencent://message/?uin= &quot; + this.txtQQ.Text + &quot;&amp;Site=im.qq.com&amp;Menu=yes &quot;;//是对方的QQ号 比如疯狂代码和傲博知识库的qq<br />
Process.Start(s); <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// 初始化窗体 <br />
/// &lt;/summary&gt; <br />
/// &lt;param name= &quot;sender &quot;&gt; &lt;/param&gt; <br />
/// &lt;param name= &quot;e &quot;&gt; &lt;/param&gt; <br />
** void QQSendMessage_Load(object sender, EventArgs e) <br />
{ <br />
this.txtGms.Text = &quot;1000 &quot;; <br />
this.txtMs.Text = &quot;1000 &quot;; <br />
} <br />
<br />
} <br />
}</p> <a href="/mypdf/11168.pdf" title="查看 qq系列之c#编写QQ群发器 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11168.html</guid>
		</item>
		<item>
			<title><![CDATA[公布一个C#编写QQ接口软件--QQ协议]]></title>
			<link>http://CrazyCoder.cn/QQDevelopment/Article11167.html</link>
			<description>
				<![CDATA[
<p>QQ的Http协议可能会把很多人迷惑了，其实通讯端口是8000而不是我们想的80，这里也可以看出腾讯的谨慎和保守、</p>
<p>下面介绍一下具体的分析</p>
<p>1、找寻支持QQ HTTP协议的服务器。</p>
<p>&nbsp;</p>
<p>很多人会认为QQ的HTTP服务器是基于80口进行通信的（如：218.17.209.23:80），其实不然，正真基于HTTP的服务器应该是：http://tqq.tencent.com:8000，它是一个通过8000口进行通讯的服务器。</p>
<p>&nbsp;</p>
<p>由于QQ的HTTP服务器并不支持HTTP协议中GET方法，它支持POST方法。所以我们要给QQ的HTTP协议传参数，那么就必需要用POST方式才行。</p>
<p>&nbsp;</p>
<p>2、C#和DELPHI是实现HTTP的POST方法的通信。</p>
<p>&nbsp;</p>
<p>C#：</p>
<p>&nbsp;</p>
<p>C#里System.<a href="/web/Index.html">Web</a>空间下提供了一个叫做<a href="/web/Index.html">Web</a>Client的对象，使用此对象就可以使C#直接对服务器发送<a href="/web/Index.html">Web</a>客户端的请求。那么我们要对服 务器提交POST方法那么就必须使用其UploadData()方法才行。首先把要请求的信息先转换为字节（因为POST提交的是字符的流数据），然后再 做为UploadData()的参数。使用UploadData()进行数据提交，最后返回，POST的回馈信息。如下：</p>
<p>&nbsp;</p>
<p><a href="/web/Index.html">Web</a>Client _client = new <a href="/web/Index.html">Web</a>Client();</p>
<p>&nbsp;</p>
<p>string postValues = &quot;VER=1.0&amp;CMD=Query_Stat&amp;SEQ=12321&amp;UIN=29501213&amp;TN=50&amp;UN=0&quot;;</p>
<p>&nbsp;</p>
<p>Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues);</p>
<p>&nbsp;</p>
<p>Byte[] pageData = _client.UploadData(Host,&quot;POST&quot;,byteArray);</p>
<p>&nbsp;</p>
<p>这样，我们就利用C#进行了一次HTTP的POST方法提交了。</p>
<p>&nbsp;</p>
<p>值在传入、返回时，其是基于UTF-8进行的，C#显示中文是很常.</p>
<p>&nbsp;</p>
<p>3、实现QQ的用户登录。</p>
<p>&nbsp;</p>
<p>在QQ通信中用户必需要登录后才可以进行互相发送信息等。QQ的登录是很关键的，大家所看到的用户在线，并不是用户的QQ一直连接着服务器，而是定时发送消信给服务器，证明自己还连着线，如果超出时间QQ就认为用户已经掉线了。</p>
<p>&nbsp;</p>
<p>在登录协议中，QQ的密码是用标准的<a href="/Tag/16228/Index.html">md5</a>来进行加密，而C#自已带有，但是直接用不了，必需进行处理后，才能使其变成标准的<a href="/Tag/16228/Index.html">md5</a>，处理代码如下：</p>
<p>&nbsp;</p>
<p>public static string <a href="/Tag/16228/Index.html">md5</a>(string toCryString)</p>
<p>&nbsp;</p>
<p>{</p>
<p>&nbsp;</p>
<p><a href="/Tag/16228/Index.html">md5</a>CryptoServiceProvider hash<a href="/Tag/16228/Index.html">md5</a>;</p>
<p>&nbsp;</p>
<p>hash<a href="/Tag/16228/Index.html">md5</a> = new <a href="/Tag/16228/Index.html">md5</a>CryptoServiceProvider();</p>
<p>&nbsp;</p>
<p>return BitConverter.ToString(hash<a href="/Tag/16228/Index.html">md5</a>.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace(&quot;-&quot;,&quot;&quot;).ToLower();//asp 是小写,把所有字符变小写</p>
<p>&nbsp;</p>
<p>}</p>
<p>&nbsp;</p>
<p>傲博知识库</p>
<p>&nbsp;</p>
<p>了解QQ是如何对用户密码加密后，那么我们就开始真正，解析QQ的HTTP登录协议了,我们把协议当传POST的参数传给服务器，而服务器则回馈相应的信息给客户端：</p>
<p>&nbsp;</p>
<p>传入协议：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Login&amp;SEQ=&amp;UIN=&amp;PS=&amp;M5=1&amp;LC=9326B87B234E7235</p>
<p>&nbsp;</p>
<p>VER是用来说明QQ协议的版本，CMD是说明协议的命令，Login就是指QQ的登录了，SEQ是他的为了防止重复发送而设定的一个标记，一般我们取当 前时间数值的一段放入即可。（C#：DateTime.Now.Ticks.ToString().Substring(7,7) DELPHI：CopyStr(inttostr(GetTickCount()),1,5)），UIN是说明你当前要登录的用户QQ号，PS，是<a href="/Tag/16228/Index.html">md5</a> 加密过后的密码的值。</p>
<p>&nbsp;</p>
<p>返回协议：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Login&amp;SEQ=11281&amp;UIN=&amp;RES=0&amp;RS=0&amp;HI=60&amp;LI=300（成功）</p>
<p>&nbsp;</p>
<p>RES为0表示成功返回，RS为0表示登录成功。</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Login&amp;SEQ=11422&amp;UIN=315103947&amp;RES=0&amp;RS=1&amp;RA=登录失败</p>
<p>&nbsp;</p>
<p>RS为1表示登录失败，那么就会出现提示信息RA说明原因。</p>
<p>&nbsp;</p>
<p>4、获得QQ名单。</p>
<p>&nbsp;</p>
<p>如果您加了您的好友，那么您的好友就会放入你的QQ的好友名单里面，那么我们要得到QQ名单就必需给QQ服务器发送得到好友名单的协议（疯狂代码就不从复已知的参数了）：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=List&amp;SEQ=&amp;UIN=&amp;TN=160&amp;UN=0</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=LIST&amp;SEQ=43661&amp;UIN=29501213&amp;RES=0&amp;FN=1&amp;SN=24&amp;UN=561256,1943497,....</p>
<p>&nbsp;</p>
<p>UN后面则是您好友的QQ号码，每个号码都由,进行分开。那么我们只需要得到UN后面的代码，把它列表化就OK了。C#可以用string.Split(',')把值放入列表进行处理，而DELPHI可以使用Split()把数值放入TStrings里进行处理。</p>
<p>&nbsp;</p>
<p>5、获得QQ好友在线名单</p>
<p>&nbsp;</p>
<p>获得QQ好友在线名单，跟获得好友名单差不多，唯一不同的是用的命令不同用的是Query_Stat，协议如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Query_Stat&amp;SEQ=&amp;UIN=&amp;TN=50&amp;UN=0</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=QUERY_STAT&amp;SEQ=-1&amp;UIN=29501213&amp;RES=0&amp;FC=141,270,270,&amp;FN=1&amp;SN=3&amp;ST=10,10,10,&amp;UN=</p>
<p>&nbsp;</p>
<p>FC为QQ头像的的ID，如的头像ID为270，那么其头使用的图片为91.bmp,其算法为ID/3+1。ST为QQ用户的状态，10为上线，20为离线，30为忙碌。UN为在线用户的QQ号，NK为在线用户的QQ昵称。ST，UN，NK，每个逗号隔开的数据相互对应。</p>
<p>&nbsp;</p>
<p>6、得到QQ用户的信息。</p>
<p>&nbsp;</p>
<p>如果要看到QQ用户的真实名称，MAIL，年龄，个人说明等信息，那么我们必需要向服务器发送得到好友信息的信息：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=GetInfo&amp;SEQ=&amp;UIN=&amp;LV=2&amp;UN=</p>
<p>&nbsp;</p>
<p>UN为要查看用户信息的QQ号。</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp; amp;CMD=GETINFO&amp;SEQ=12707&amp;UIN=415103947&amp;RES=0&amp;AD=云南昆明&amp; amp;AG=0&amp;EM=Microprogramer@hotmail.com&amp;FC=270&amp;HP=msger.org(建 设中...)&amp;JB=程序员&amp;LV=2&amp;PC=650000&amp;PH=0871-6466529&amp;PR=网络为 媒%252c关系为本%252c信息为财%252c客户为主.%0d%0a&amp;PV=云南省&amp;RN=刘X&amp;SC=社会大学&amp; amp;SX=0&amp;UN=24259132&amp;NK=微程</p>
<p>&nbsp;</p>
<p>AD用户的联系地址，AG为用户年龄，EM为用户MAIL，FC 为用户头像，HP为用户网站，JB为用户职业，PC为用户邮编，PH为用户联系电话，PR为用户简介，PV为用户所以的省，RN为用户真实名称，SC为用 户毕业院校，SX为用户性别，UN为用户QQ号，NK为用户QQ昵称。</p>
<p>&nbsp;</p>
<p>7、增加QQ好友。</p>
<p>&nbsp;</p>
<p>想要新增好友，就要发送AddToList命令给服务器，具体命令如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=AddToList&amp;SEQ=&amp;UIN=&amp;UN=</p>
<p>&nbsp;</p>
<p>UN为我们要增加用户的QQ号。</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=AddToList&amp;SEQ=13666&amp;UIN=415103947&amp;RES=0&amp;CD=0&amp;UN=24259132</p>
<p>&nbsp;</p>
<p>CD 为被加QQ的身份验证状态，CD为0表示&ldquo;允许任何人把我列为好友&rdquo;，CD为1表示&ldquo;需要身份证认才能把我列为好友&rdquo;，CD为3表示&ldquo;不允许任何人把我列 为好友&rdquo;。如果CD为0那么信息回馈后，用户就直接加为好友了，如果CD为1，那么还要发送一次回应加为好友的响应。</p>
<p>&nbsp;</p>
<p>8、回应加为好友的响应。</p>
<p>&nbsp;</p>
<p>回应加为好友响应是双方的：1、如果你发送了请求加对方为好友，如果对方需要验证，那么必需发送回应加为好友的响应。2、如果对方发送加为好友请求给你，那么你可以加应加为好友的响应，一是加为好友，一是通过验证，一是拒决加为好友。我们要向服务器发送命令：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=&amp;UIN=&amp;UN=&amp;CD=&amp;RS=</p>
<p>&nbsp;</p>
<p>CD为响应状态，CD为0表示&ldquo;通过验证&rdquo;。CD为1表示&ldquo;拒决加为对方为好友&rdquo;。CD为2表示&ldquo;为请求对方加为好友&rdquo;。RS为你要请求的理由.</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=1130&amp;UIN=415103947&amp;RES=0&amp;</p>
<p>&nbsp;</p>
<p>9、删除好友。</p>
<p>&nbsp;</p>
<p>删除好友其实很容易，向服务器发送DelFromList命令则可以删除用户：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=DelFromList&amp;SEQ=&amp;UIN=&amp;UN=</p>
<p>&nbsp;</p>
<p>UN为要删除用户的QQ号。</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=DelFromList&amp;SEQ=24514&amp;UIN=415103947&amp;RES=0&amp;</p>
<p>&nbsp;</p>
<p>10、改变用户当前状态。</p>
<p>&nbsp;</p>
<p>可以把QQ设置为在线，隐身等状态，我们可以发送Change_Stat给服务器以改变当前状态，具体命令如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Change_Stat&amp;SEQ=&amp;UIN=&amp;ST=</p>
<p>&nbsp;</p>
<p>ST为要改变的状态，10为上线，20为离线，30为忙碌。</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Change_Stat&amp;SEQ=17512&amp;UIN=415103947&amp;RES=0&amp;</p>
<p>&nbsp;</p>
<p>11、退出登录</p>
<p>&nbsp;</p>
<p>要退出登录，要向服务器发送命令Logout，具体命令如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=Logout&amp;SEQ=&amp;UIN=</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=LOGOUT&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0</p>
<p>&nbsp;</p>
<p>12、获得好友QQ的消息</p>
<p>&nbsp;</p>
<p>如果要接收好友的消息，要向服务器发送命令GetMsgEx，具体命令如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=GetMsgEx&amp;SEQ=&amp;UIN=</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=GETMSGEX&amp;SEQ=56661&amp;UIN=29501213&amp;RES=0&amp;MN=3&amp;MT=99,9,9,&amp;UN=24259132,24259132,24259132,&amp;MG=30 ,asdfasdfasdfasdf ,asdfasdfasdf ,&amp;</p>
<p>&nbsp;</p>
<p>MT表示消息类型，99表示系统消息，9表示用户消息。 UN表示消息发送来源用户，MG表示发送的消息，MG消息可以表示某些特定的系统含意，譬如：当MT为99，MG为30，UN为24259132则表示用 户4259132现在处于忙碌状态，可根据此消息进行好友列表的刷新，提高效率。</p>
<p>&nbsp;</p>
<p>13、向好友QQ发送消息</p>
<p>&nbsp;</p>
<p>要发送消息给好友，要向服务器发送命令CLTMSG命令，具体命令如下：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=CLTMSG&amp;SEQ=&amp;UIN=&amp;UN=&amp;MG=</p>
<p>&nbsp;</p>
<p>UN为消息发送给的用户QQ号码，MG为发送给该用户的消息。</p>
<p>&nbsp;</p>
<p>服务器得到协议后如果成功则返回：</p>
<p>&nbsp;</p>
<p>VER=1.1&amp;CMD=CLTMSG&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0</p>
<p>&nbsp;</p>
<p>好了，以上就是QQ基于HTTP的一个不完全的协议分析，利用以上协议您就可以实现很多东西，如：QQ机器人，QQ广告系统，即时通讯的整合工具等等</p>
<p>&nbsp;</p>
<p>QQ协议网络协议--请求部份</p>
<p>&nbsp;</p>
<p>//登录</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Login&amp;SEQ=&amp;UIN=&amp;PS=&amp;M5=1&amp;LC=9326B87B234E7235</p>
<p>&nbsp;</p>
<p>//获取消息</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=GetMsgEx&amp;SEQ=&amp;UIN=</p>
<p>&nbsp;</p>
<p>//发送消息</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=CLTMSG&amp;SEQ=&amp;UIN=&amp;UN=&amp;MG=</p>
<p>&nbsp;</p>
<p>//朋友列表</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=List&amp;SEQ=&amp;UIN=&amp;TN=160&amp;UN=0</p>
<p>&nbsp;</p>
<p>//获取好友状态</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Query_Stat&amp;SEQ=&amp;UIN=&amp;TN=50&amp;UN=0</p>
<p>&nbsp;</p>
<p>//获取好友信息</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=GetInfo&amp;SEQ=&amp;UIN=&amp;LV=2&amp;UN=</p>
<p>&nbsp;</p>
<p>//增加好友</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=AddToList&amp;SEQ=&amp;UIN=&amp;UN=</p>
<p>&nbsp;</p>
<p>//回应对方请求加你为好友的响应</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Ack_AddToList&amp;SEQ=&amp;UIN=&amp;UN=&amp;CD=&amp;RS=</p>
<p>&nbsp;</p>
<p>//删除好友</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=DelFromList&amp;SEQ=&amp;UIN=&amp;UN=</p>
<p>&nbsp;</p>
<p>//搜索好友</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Finger&amp;SEQ=&amp;UIN=&amp;AG=&amp;SX=&amp;PV=</p>
<p>&nbsp;</p>
<p>//改变自己状态，ST的代码应该和获取好友状态代码一致</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Change_Stat&amp;SEQ=&amp;UIN=&amp;ST=</p>
<p>&nbsp;</p>
<p>//退出登录</p>
<p>&nbsp;</p>
<p>VER=1.0&amp;CMD=Logout&amp;SEQ=&amp;UIN=</p> <a href="/mypdf/11167.pdf" title="查看 公布一个C#编写QQ接口软件--QQ协议 的PDF电子文档">[查看PDF电子文档]</a>				]]>
			</description>
			<author></author>
			<category>QQ协议开发</category>
			<pubDate>2008-09-21</pubDate>
			<guid>http://CrazyCoder.cn/QQDevelopment/Article11167.html</guid>
		</item>
	</channel>
</rss>
