QQ推出过可以了解你和你的好友之间有多少个共同好友的功能。 获取QQ好友列表信息
有时候,我会好奇。咦,这个共同好友都会有谁呢,咱们的交际圈子相互认识的都会有谁呢?这是一个好玩的问题哈。会不会觉得很神奇。是的,我们活在圈子下,指不定哪天,大家聚在一起,才发现世界这么的小,原来你我之间的距离这么近。好了,抒情了一段,下面说说本文要做的事情:本文的最终目的旨在揪出这些共同好友的QQ号码。(因为当时做这个实验是一年多前做的,现在凭借回忆写的,所有有一些地方可能写的不对或者有错,或者没有写出来)
思路: 1、获取双方的QQ好友列表
2、求交集,得到共同好友。
别看思路这么简单,实现起来可不容。本案例的难点重点在于如何获取到双方的QQ好友列表,这是个头疼的问题。想想,腾讯那么牛X。肯定不会轻易将这种信息给你破解的了。qq软件在本地缓存文件夹下建立本地数据库,以.db文件形式存在,这个路径可以在QQ的设置中找到。如图所示。
对应QQ号缓存本地信息文件结构
这这里面的所有.db就是QQ软件所需的个人所有个人信息。包括好友信息、头像信息、聊天信息(聊天信息的加解密算法是最麻烦的)等等。我们需要在这些.db文件中找到我们要的好友列表信息。这个工作可不好做。
Firstofall,我找了一篇大牛的文章来研究。文章名字叫做“基于QQ的DB文件格式解析”这个网上应该找的到,自己去找一下啦。他说讲的QQ本地数据文件结构应该是好几年前的了,文件结构可能对不上,当时加密算法是OK的。我把其中一段截图下来来作说明。
基于QQ的DB文件格式解析
文章截图
非常感谢这篇文章的作者。在这篇文章中,我们知道了QQ对好友列表信息是如何加密的。51
44 代表是QQ好友信息;A9B5 B2
是1S标志,即QQ号码标志;04 00 00 00是1S数据的长度;9A 4D 1F 04是QQ号码,即69160346
0x041F4D9A(高位在前)。OK
,这便是我们需要的——好友的QQ号。把所有的QQ号码都找到就能找到该QQ号的所有好友列表了。
这一步操作目的明确了后,那么我们就需要知道到底哪个.db文件是存储的QQ好友列表信息的。(这里我忘记是怎么找到得了,确实忘记了。希望大神能帮我补充一下。)
这里用EditPlus对.db文件查看,open
with Encoding选择Hex
viewer编码。这里看到的是十六进制的一系列数据,其中就有上述所说的QQ好友的信息。
Hex
viewer编码下.db文件数据
假设已经找到对应的
xxxx.db文件是存储好友列表信息的。为了后面方便对这些十六进制数操作,我将对应的所有数据复制到txt文件中(注意:目前我发现只能用EditPlus将数据Ctrl+c,Ctrl+v复制到txt里面),如下如所示。获取QQ好友列表信息
txt复制文件内容
接下来就是要实现筛选和转换数据的功能,我使用的是C#来作这件事,把对应的数据获取存到数据中就OK,要说的是,数据库我做的很简单,用的MSSQL,两张表,一张A表存QQ号A的好友列表,一张B表存QQ号B的好友列表。结构如下,最后用SQL查询做对比就OK了。
数据库表结构
下面把实现提取数据存入数据库功能的主要代码贴上来(程序写的比较渣,没优化,没调整)。
class Program
{
byte[] byData = new byte[100];
char[] charData = new char[1000];
static void Main(string[] args)
{
Read("C:\\Users\\Administrator\\Desktop\\QQDB\\测试\\XXXXXXX.txt");//改成你的txt文件
}
static public void Read(string url)
{
StreamReader sr = new StreamReader(url,
Encoding.Default);
String
line;
while
((line = sr.ReadLine()) != null)
{
string
before=line.ToString();//在做截取之前的字符串
string after="";
int index =
line.ToString().IndexOf("04");
int
len=line.ToString().Length;
string str = "";
if(index==45)//"04位于最后面的位子,读取下一行的内容
{
if((line=sr.ReadLine())!=null)//读取的下一行不为空
{
if(line.ToString().IndexOf("00 00 00")==0)//前一个位子是00 00
00
{
str=line.ToString().Substring(9,11);
}
}
}
else
if(index==42)//在倒数第二个位子,后面是否为00,再读取下一行
{
if (before.Substring(45) == "00")
{
if ((line
= sr.ReadLine()) != null)//读取的下一行不为空
{
if
(line.ToString().IndexOf("00 00") == 0)
{
str = line.ToString().Substring(6,
11);
}
}
}
}
else if (index ==
39)
{
if (before.Substring(42) == "00 00")
{
if ((line
= sr.ReadLine()) != null)//读取的下一行不为空
{
if
(line.ToString().IndexOf("00") == 0)
{
str = line.ToString().Substring(3,
11);
}
}
}
}
else if (index ==
36)
{
if (before.Substring(39) == "00 00
00")
{
if ((line
= sr.ReadLine()) != null)//读取的下一行不为空
{
str =
line.ToString().Substring(0, 11);
}
}
}
else
{
if (before.Substring(index + 3, 8) == "00 00
00")
{
index =
index + 12;
after =
line.Substring(index);
if
(after.Length < 11)
{
str = after;
if ((line = sr.ReadLine()) !=
null)//读取的下一行不为空
{
str += " " + line.ToString().Substring(0, 11 -
after.Length-1);
}
}
else
{
str=line.Substring(index,11);
}
}
}
if (str != "")
{
string a = str.Substring(0, 2);
string b = str.Substring(3, 2);
string c = str.Substring(6, 2);
string d = str.Substring(9, 2);
string newstr = d + c + b + a;
int aaa =
Convert.ToInt32(newstr,16);
Add(aaa.ToString());
}
}
}
static public void Add(string sqlstr)
{
string aa
= "server=.;database=QQFriendList;uid=sa;pwd=admin123";
SqlConnection conn = new SqlConnection(aa);
SqlCommand
comm = new SqlCommand("insert into [dbo].[ListB]([ListBdeQQ])
values ('" + sqlstr + "')", conn);//ListA存了,存ListB
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
}
}
将两方的数据都存入数据库后,在做个求交集的SQL语句,答案就出来了。文玩业 代码如下。
select DISTINCT [ListBdeQQ] from
(select * from [dbo].[ListB] where [ListBdeQQ] in (select
[ListAdeQQ] from [dbo].[ListA]))
as C
where [ListBdeQQ]>10000
求交集结果
这个便是两个QQ好友之间共同好友的QQ号,但是这里需要说的是,这里的QQ号,不一定都是的,有一些是无用数据,在QQ上手动一条一条看就可以了。QQ好友列表获取软件
来源:http://qq.gam7.com
网友评论