qq好友列表获取hash算法解析-web版QQ

在使用web qq的接口进行qq好友列表获取的时候,需要post一个参数:hash

在对其js文件进行分析之后,发现计算hash的函数位于:

http://0.web.qstatic.com/webqqpic/pubapps/0/50/eqq.all.js

这个文件中:

P = function(b, i) {
				for (var a = [], s = 0; s < i.length; s++) a[s % 4] ^= i.charCodeAt(s);
				var j = ["EC", "OK"],
				d = [];
				d[0] = b >> 24 & 255 ^ j[0].charCodeAt(0);
				d[1] = b >> 16 & 255 ^ j[0].charCodeAt(1);
				d[2] = b >> 8 & 255 ^ j[1].charCodeAt(0);
				d[3] = b & 255 ^ j[1].charCodeAt(1);
				j = [];
				for (s = 0; s < 8; s++) j[s] = s % 2 == 0 ? a[s >> 1] : d[s >> 1];
				a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
				d = "";
				for (s = 0; s < j.length; s++) d += a[j[s] >> 4 & 15],
				d += a[j[s] & 15];
				return d
		}


这样可以写一个python版本:

a=[0,0,0,0]
		s=0
		for s in range(0,len(i)):
			a[s%4] = a[s%4] ^ ord(i[s])
		j = ["EC", "OK"]
		d = [0,0,0,0]
		d[0] = int(b) >> 24 & 255 ^ ord(j[0][0])
		d[1] = int(b) >> 16 & 255 ^ ord(j[0][1])
		d[2] = int(b) >> 8 & 255 ^ ord(j[1][0])
		d[3] = int(b) & 255 ^ ord(j[1][1])
		j = range(0,8)
		for s in range(0,8):
			if s % 2 == 0:
				j[s] = a[s >> 1]
			else:
				j[s] = d[s >> 1]
		a = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
		d = ""
		for s in range(0,len(j)):
			d = d + a[j[s] >> 4 & 15]
			d = d + a[j[s] & 15]
		return d


但是第二天使用web qq接口实现qq好友列表获取时,却不能获取了。后来发现原来是这个hash函数变了:

P = function(b, i) {
			for (var a = [], s = 0; s < b.length; s++) a[s] = b.charAt(s) - 0;  alert(a);//ago
			for (var j = 0, d = -1, s = 0; s < a.length; s++) {
				j += a[s];
				j %= 
				i.length;
				var c = 0;
				if (j + 4 > i.length) for (var l = 4 + j - i.length, x = 0; x < 4; x++) c |= x < l ? (i.charCodeAt(j + x) & 255) << (3 - x) * 8: (i.charCodeAt(x - l) & 255) << (3 - x) * 8;
				else for (x = 0; x < 4; x++) c |= (i.charCodeAt(j + x) & 255) << (3 - x) * 8;
				d ^= c
			}
			a = [];
			a[0] = d >> 24 & 255;
			a[1] = d >> 16 & 255;
			a[2] = d >> 8 & 255;
			a[3] = d & 255;
			d = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
			s = "";
			for (j = 0; j < a.length; j++) s += d[a[j] >> 4 & 15],
			s += d[a[j] & 15];
			return s
		}

继续改写成python版:

a=[]
		s=0
		for s in range(0,len(b)):
			t=int(b[s])
			a.append(t)	
		j = 0
		d = -1
		s = 0
		for s in range(0,len(a)):
			j = j + a[s]
			j = j % len(i)
			c = 0
			if (j + 4) > len(i): 
				l = 4 + j - len(i)
				for x in range(0,4):
					if x < l:
						c = c | (( ord(i[j + x]) & 255) << (3 - x) * 8 )
					else:
						c = c | ( ( ord(i[x - l]) & 255) << (3 - x) * 8 )
			else:
				for x in range(0,4):
					c = c | (( ord(i[j + x]) & 255) << (3 - x) * 8 )
			d = d ^ c	
			
		a = [0,0,0,0]
		a[0] = d >> 24 & 255
		a[1] = d >> 16 & 255
		a[2] = d >> 8 & 255
		a[3] = d & 255
		d = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
		s = ""
		for j in range(0,len(a)):
			s = s + d[a[j] >> 4 & 15]
			s = s + d[a[j] & 15]
		return s

更多qq好友列表获取实现方法 可以加Q:2163927521  一起交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
列表是一种基于哈希函数实现的数据结构,可以快速地存储和查找数据。在实现QQ账户的申请与登录时,我们可以使用散列表来存储用户的账号和密码信息。 具体的算法思路如下: 1. 定义一个结构体来存储用户的账号和密码信息,例如: ```c++ struct Account { string username; // 用户名 string password; // 密码 }; ``` 2. 定义一个哈希函数,将用户名转换成一个整数作为散列表的下标,例如: ```c++ int hashFunction(string username) { int hash = 0; for (char c : username) { hash = hash * 31 + c; } return hash; } ``` 这里使用了一个简单的哈希函数,将每个字符的ASCII码乘以31后相加,得到一个整数作为哈希。 3. 定义一个散列表,使用vector来存储链表,每个链表存储哈希相同的账号信息,例如: ```c++ const int MAX_SIZE = 1000000; // 散列表的最大大小 vector<Account> hashTable[MAX_SIZE]; // 散列表 void insertAccount(Account account) { int idx = hashFunction(account.username) % MAX_SIZE; hashTable[idx].push_back(account); } Account* findAccount(string username) { int idx = hashFunction(username) % MAX_SIZE; for (Account& account : hashTable[idx]) { if (account.username == username) { return &account; } } return nullptr; } ``` 这里使用了链表来解决哈希冲突的问题,如果不同的用户名产生了相同的哈希,就将它们存储在同一个链表中。 4. 在用户注册时,将账号和密码信息插入到散列表中: ```c++ Account account; cout << "请输入用户名:"; cin >> account.username; cout << "请输入密码:"; cin >> account.password; insertAccount(account); ``` 5. 在用户登录时,根据输入的用户名在散列表中查找对应的账号信息,然后判断密码是否正确: ```c++ string username, password; cout << "请输入用户名:"; cin >> username; cout << "请输入密码:"; cin >> password; Account* accountPtr = findAccount(username); if (accountPtr && accountPtr->password == password) { cout << "登录成功!" << endl; } else { cout << "用户名或密码错误!" << endl; } ``` 如果找到了对应的账号信息,并且密码正确,就认为登录成功。否则,认为用户名或密码错误。 以上就是使用散列表实现QQ账户的申请与登录的算法思路。当然,实际应用中还需要考虑许多其他因素,例如密码加密、防止散列表溢出等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值