forked from roadwide/qqmessageoutput
-
Notifications
You must be signed in to change notification settings - Fork 0
/
q.py
129 lines (115 loc) · 4.35 KB
/
q.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from _overlapped import NULL
import hashlib
import sqlite3
import time
class QQoutput():
# 初始化解密key,并连接sqlite3数据库
def __init__(self, db, key):
self.key = key # 解密用的密钥
self.c = sqlite3.connect(db).cursor()
# 解密数据,针对不同数据用不同的方法
def fix(self, data, mode):
# msgdata mode=0
# other mode=1
if (mode == 0):
rowbyte = []
# 这么做是为了解决汉字的utf-8是三字节
if data == None:
data=''
for i in range(0, len(data)):
rowbyte.append(data[i] ^ ord(self.key[i % len(self.key)]))
rowbyte = bytes(rowbyte)
try:
msg = rowbyte.decode(encoding='utf-8')
except:
msg = NULL
return msg
elif (mode == 1):
str = ''
try:
j = 0
for i in range(0, len(data)):
# 获取unicode码
unicode = ord(data[i])
# 如果大于ffff 处理emoji
if (unicode > 0xffff):
# 分为2个10位二进制与两个密码进行异或
code = unicode ^ ((ord(self.key[i+j % len(self.key)])<<10) + ord(self.key[i+j+1 % len(self.key)]))
str += chr(code)
j = j + 1
else:
str += chr(ord(data[i]) ^ ord(self.key[i+j % len(self.key)]))
except:
str = NULL
return str
# 获得聊天记录
def message(self, num, mode):
# mode=1 friend
# mode=2 troop
num = str(num).encode('utf-8')
md5num = hashlib.md5(num).hexdigest().upper()
if (mode == 1):
execute = "select msgData,senderuin,time from mr_friend_{md5num}_New".format(md5num=md5num)
elif (mode == 2):
execute = "select msgData,senderuin,time from mr_troop_{md5num}_New".format(md5num=md5num)
else:
print("error mode")
exit(1)
cursor = self.c.execute(execute)
allmsg = []
for row in cursor:
msgdata, uin, ltime = row[0], row[1], time.localtime(row[2])
sendtime = time.strftime("%Y-%m-%d %H:%M:%S", ltime)
msg = self.fix(msgdata, 0)
senderuin = self.fix(uin, 1)
print([sendtime, senderuin, msg])
allmsg.append([sendtime, senderuin, msg])
return allmsg
# 输出到文件
# 导出聊天记录
def output(self, num, mode):
file = str(num) + ".html"
f2 = open(file, 'w', encoding="utf-8")
f2.write("<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /></head>")
allmsg = self.message(num, mode)
for msg in allmsg:
try:
f2.write("<font color=\"blue\">")
f2.write(msg[0])
f2.write("</font>-----<font color=\"green\">")
f2.write(msg[1])
f2.write("</font></br>")
f2.write(msg[2])
f2.write("</br></br>")
except:
pass
# 获得所有好友昵称,备注,QQ等数据,包括临时会话的人以及一些不知道哪来的人
def getAllMyFriends(self):
FriendsData = []
# uin-QQ号,remark-备注,name-昵称
execute = "select uin,remark,name from Friends"
cursor = self.c.execute(execute)
with open("FriendsData.txt", "w+", encoding="utf-8") as f:
for i in cursor:
uin, remark, name = i[0], i[1], i[2]
decode_uin = self.fix(uin, 1)
decode_remark = self.fix(remark, 1)
decode_name = self.fix(name, 1)
print("QQ:{}\t备注:{}\t昵称:{}".format(decode_uin, decode_remark, decode_name), file=f)
FriendsData.append([decode_uin, decode_remark, decode_name])
return FriendsData
# config
# 储存QQ聊天信息的db文件,以你的QQ号命名
dbfile = 'yourdb.db'
# 解密的key
key = ''
# 导出模式,1是好友,2是群
mode = 1
# 导出的聊天对象
yourfriendqq = 123456
# 初始化
q = QQoutput(dbfile, key)
# 获得所有好友的个人资料
q.getAllMyFriends()
# 导出聊天记录
q.output(yourfriendqq, mode)