- 浏览: 31482 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
li4li5li6:
tsinlei 写道搞JSP非要用到MyEclipse插件吗? ...
原来是这样——Eclipse编辑JSP文件假死现象 -
tsinlei:
搞JSP非要用到MyEclipse插件吗?
原来是这样——Eclipse编辑JSP文件假死现象 -
cszhujian:
authimgs_idli4li5li6 写道cszhujia ...
邀请QQ好友-QQ联系人导入 -
li4li5li6:
cszhujian 写道li4li5li6 写道mywes 写 ...
邀请QQ好友-QQ联系人导入 -
cszhujian:
li4li5li6 写道mywes 写道你好,楼主,我把你的代 ...
邀请QQ好友-QQ联系人导入
项目中有个需求,要求能够导入MSN及QQ联系人。MSN的好说,有开源的jmsn及其它众多开源组件。可是QQ仍然是我行我素,至今也不开放API。虽然网上查到有lumaqq这样的开源
协议,可我Down下了折腾了半天,QQ都没有登录上去,好啦,我承认自己资质愚钝。时间紧迫,来不及仔细研究了,于是打起了QQ邮箱的主意~~
既然通过浏览器可以登录QQ邮箱,查看联系人,那么我们同样可以用程序模拟浏览器登录获取联系人。嗯,听起来不错,试试吧。
登录请求:
POST /cgi-bin/login?sid=0,2,zh_CN HTTP/1.1 Host: m126.mail.qq.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.0.13) Gecko/2009073022 Firefox/3.0.13 (.NET CLR 3.5.30729) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://mail.qq.com/cgi-bin/loginpage Cookie: verifysession=c6c09b326c4dac79b727c7e6e1069238e9bfe9ae6e7943e740a535af7cc57bddeacf1b617a15a912; pvid=5429125866; flv=10.0 r22; }; r_cookie=9828306541 Content-Type: application/x-www-form-urlencoded Content-Length: 371 sid=0%2C2%2Czh_CN&firstlogin=false&starttime=1251436516205&redirecturl=&f=html&p=UyoLX7JYspcnU9wCUK7qBA2Xjwo%2FO52FldnJnRABCnNLXI1ndwR8%2BQaepkT% 2FIcKHxMshWv4SjrxgvRtA%2B1eHAookTXzcia%2FhP5QrRlGyNoqzVCi1X%2FsJwb4SmjPZRwV%2B7WeskUwClUfeNv%2BmCq0ygoNzi9UnIVeI7lYzgqXnxZE% 3D&delegate_url=&s=&ts=1251436494&from=&uin=XXXXXXXX&aliastype=%40qq.com&pp=000000000&verifycode=qmpb
响应:
HTTP/1.1 200 OK Connection: close Date: Fri, 28 Aug 2009 05:15:18 GMT Content-Type: text/html; charset=gbk Set-Cookie:tinfo=1251436518.0550; Domain=mail.qq.com; Path=/ Set-Cookie:wimrefreshrun=; Domain=mail.qq.com; Path=/ Set-Cookie:autologin=EXPIRED; Domain=mail.qq.com; Path=/; Expires=Fri, 28-Aug-2009 05:17:18 GMT Set-Cookie:sid=; Domain=mail.qq.com; Path=/; Expires=Wed, 31-Dec-1969 23:59:59 GMT Set-Cookie:sid=6449e26f4adc402ac5c80e08bec3ca6c; Domain=mail.qq.com; Path=/ Set-Cookie:username=; Domain=mail.qq.com; Path=/; Expires=Wed, 31-Dec-1969 23:59:59 GMT Set-Cookie:username=XXXXXXXX; Domain=mail.qq.com; Path=/ Set-Cookie:qqmail_alias=XXXXXXXX@qq.com; Domain=mail.qq.com; Path=/ Set-Cookie:qqmail_sid=6449e26f4adc402ac5c80e08bec3ca6c; Domain=qq.com; Path=/ Set-Cookie:qqmail_username=XXXXXXXX; Domain=qq.com; Path=/ Set-Cookie:qqmail_domain=http://m126.mail.qq.com; Domain=qq.com; Path=/ Set-Cookie:qqmail_key=1_de7d3652ab10a1616175bf2aab152fb7010b0d06020602060309; Domain=qq.com; Path=/ Set-Cookie:CCSHOW=0000; Domain=mail.qq.com; Path=/; Expires=Sun, 28-Oct-2012 15:01:58 GMT Set-Cookie:noteorg=; Domain=mail.qq.com; Path=/; Expires=Sun, 28-Oct-2012 15:01:58 GMT Set-Cookie:foxacc=0; Domain=mail.qq.com; Path=/; Expires=Sun, 28-Oct-2012 15:01:58 GMT Set-Cookie:edition=4m126.mail.qq.com; Domain=mail.qq.com; Path=/; Expires=Sun, 28-Oct-2012 15:01:58 GMT Content-Encoding: gzip Content-Length: 356
通过分析QQ邮箱登录页,发现除了QQ号码和密码之外,还有几个隐藏字段。
sid 常量
firstlogin 常量
starttime
redirecturl 常量
f 常量
p
delegate_url 常量
s 常量
ts
from 常量
uin
aliastype
pp
verifycode
大部分都不清楚什么用途,且都是固定的。
有用的就是 starttime(js生成的当前时间戳)、p(QQ号码和密码混合加密后生成的字符串)、ts(某种算法生成的时间戳,来自服务器)、uin(QQ号码)、aliastype(邮箱域
,通常是 @qq.com)、pp(密码掩码)、verifycode(验证码)
还有几个Cookie:
verifysession(获取验证码时服务器种下的)
pvid、flv、r_cookie(看起来像是跟踪用的)
OK,我们把这些参数及Cookie发送给服务器,就可以登录了。
再做一些加工,一个导入QQ联系人的组件就诞生了,不过这些代码却脆弱无比,只要qq邮箱一更新,那怕少一个空格,我这几个小时的代码就变成垃圾了。所以,如果想用到正
式的项目上,你就要时刻准备更新你的程序~~
ie7 firefox 下测试通过,google浏览器下总说验证码错误。
不多说了,上代码
-----------------QQContactsService.java------------------------------------------------
package qq; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; public class QQContactsService { private static QQContactsService qcs = new QQContactsService(); public static QQContactsService getInstance(){ return qcs; } public static final RuntimeException QQ_EEROR = new RuntimeException( "qq server error"); public static final RuntimeException QQ_WRONG_PWD = new RuntimeException("qq wrong password"); public static final RuntimeException QQ_WRONG_VERIFY = new RuntimeException("qq wrong verify"); public static final RuntimeException QQ_MANY_LOGIN_TIMES = new RuntimeException("qq too many login times"); public RSAInfo getRSAInfo() { String loginPage = "http://mail.qq.com/cgi-bin/loginpage"; HttpClient httpClient = newHttpClient(); GetMethod getLoginPage = new GetMethod(loginPage); try { int code = httpClient.executeMethod(getLoginPage); if (code != 200) throw QQ_EEROR; String body = getLoginPage.getResponseBodyAsString(); String publicKey = QQUtil.paser(body,QQUtil.publicKeyPattern); String ts = QQUtil.paser(body,QQUtil.tsPattern); String domain = QQUtil.paser(body,QQUtil.domainPattern); if (publicKey == null || ts == null || domain == null) throw QQ_EEROR; return new RSAInfo(publicKey, ts, domain); } catch (IOException e) { e.printStackTrace(); throw QQ_EEROR; } } public VerifyCode getVerifyCode() { HttpClient httpClient = newHttpClient(); GetMethod getVerifyPage = new GetMethod(getVerifyUrl()); try { int code = httpClient.executeMethod(getVerifyPage); if (code != 200) throw QQ_EEROR; System.out.println("code:"+code); byte[] data = getVerifyPage.getResponseBody(); Cookie[] cookies = httpClient.getState().getCookies(); Cookie verifySession = pickUpVerifySessionCookie(cookies); System.out.println("verifySession:"+verifySession+",data:"+data); if (data == null || verifySession == null) throw QQ_EEROR; return new VerifyCode(verifySession, data); } catch (IOException e) { e.printStackTrace(); throw QQ_EEROR; } } public List<QQContact> getQQContacts(AuthInfo authInfo) { login(authInfo); String contactsHtml = getQQContactsPage(authInfo); return QQUtil.parserQQContects(contactsHtml); } private String getQQContactsPage(AuthInfo authInfo) { //http://m154.mail.qq.com/cgi-bin/addr_listall?sid=iaVXkE2ACz61dmYs&category=qq String domain = authInfo.getParam(AuthInfo.DOMAIN); String sid = authInfo.getParam("sid"); String contactUrl = domain+"/cgi-bin/addr_listall?sid="+sid+"&category=qq"; GetMethod getAllContect = new GetMethod(contactUrl); getAllContect.setRequestHeader("Cookie", authInfo.getParam(AuthInfo.COOKIE)); getAllContect.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; InfoPath.2; CIBA)"); HttpClient httpClient = newHttpClient(); try { httpClient.executeMethod(getAllContect); String body = new String(getAllContect.getResponseBody(),"gbk"); return body; } catch (IOException e) { e.printStackTrace(); throw QQ_EEROR; } } private void login(AuthInfo authInfo){ fillPvidAndRCookie(authInfo); String domain = authInfo.getParam(AuthInfo.DOMAIN); PostMethod postMethod = new PostMethod(domain+"/cgi-bin/login?sid=0,2,zh_CN"); postMethod.setRequestBody(toNameValuePer(authInfo)); postMethod.setRequestHeader("Cookie", authInfo.getParam(AuthInfo.COOKIE)); postMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); postMethod.setRequestHeader("Referer", "http://mail.qq.com/cgi-bin/loginpage"); postMethod.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; GTB5; InfoPath.2; CIBA)"); HttpClient httpClient = newHttpClient(); try { int status = httpClient.executeMethod(postMethod); if(status != 200 ) throw QQ_EEROR; String body = postMethod.getResponseBodyAsString(); System.out.println("body:"+body); String sid = QQUtil.paser(body, QQUtil.sidPattern); if(sid == null){ String errType = QQUtil.paser(body, QQUtil.errTypePattern); if("1".equals(errType)) throw QQ_WRONG_PWD; if("2".equals(errType)) throw QQ_WRONG_VERIFY; if("17".equals(errType)) throw QQ_MANY_LOGIN_TIMES; throw QQ_EEROR; } System.out.println("sid:"+sid); Cookie[] cookies = httpClient.getState().getCookies(); addCookie(authInfo,cookies); authInfo.putParam("sid", sid); System.out.println("set sid:"+authInfo.getParam("sid")); }catch (IOException e) { e.printStackTrace(); throw QQ_EEROR; } } private NameValuePair[] toNameValuePer(AuthInfo authInfo) { List<NameValuePair> nvp = new ArrayList<NameValuePair>(); Map<String,String> params = authInfo.getParam(); for (Map.Entry<String, String> entry : params.entrySet()) { if(!entry.getKey().equals(AuthInfo.COOKIE) && !entry.getKey().equals(AuthInfo.DOMAIN)){ nvp.add(new NameValuePair(entry.getKey(),entry.getValue())); } } return nvp.toArray(new NameValuePair[nvp.size()]); } private HttpClient newHttpClient() { HttpClient c = new HttpClient(); c.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); return c; } private String getVerifyUrl() { return "http://ptlogin2.qq.com/getimage?aid=23000101&" + Math.random(); } private Cookie pickUpVerifySessionCookie(Cookie[] cookies) { for (Cookie c : cookies) { System.out.println("cookie:"+c.getName()); if ("verifysession".equalsIgnoreCase(c.getName())) { return c; } } return null; } private void fillPvidAndRCookie(AuthInfo authInfo) { String cookie = authInfo.getParam(AuthInfo.COOKIE); cookie+=newPvid(); cookie+=newRCookie(); authInfo.putParam(AuthInfo.COOKIE, cookie); } private String newPvid() { long pvidtmp = (Math.round(Math.random() * 2147483647) * 199) % 10000000000L; return "pvid="+pvidtmp+";"; } private String newRCookie() { long r_cookie = Math.round(Math.random() * 1000000000000L); return "r_cookie="+r_cookie+";"; } private void addCookie(AuthInfo authInfo, Cookie[] cookies){ String cookie = authInfo.getParam(AuthInfo.COOKIE); for(Cookie c : cookies){ cookie += c.toString()+";"; } System.out.println("addCookie:"+cookie); authInfo.putParam(AuthInfo.COOKIE, cookie); } public static void main(String[] args) { QQContactsService service = QQContactsService.getInstance(); RSAInfo rsa = service.getRSAInfo(); System.out.println("rsa:"+rsa.getDomain()+","+rsa.getPublicKey()+","+rsa.getTs()); service.getVerifyCode(); } }
---------------AuthInfo.java----------------------------
package qq; import java.util.HashMap; import java.util.Map; public class AuthInfo { public static final String PP = "pp"; public static final String START_TIME = "starttime"; public static final String TS = "ts"; public static final String UIN = "uin"; public static final String VERIFY_CODE = "verifycode"; public static final String P = "p"; public static final String COOKIE = "cookie"; public static final String DOMAIN = "domain"; private HashMap<String, String> param = new HashMap<String,String>(); public AuthInfo(){ putParam("aliastype", "@qq.com"); putParam("firstlogin", "false"); putParam("redirecturl", ""); putParam("sid", "0,2,zh_CN"); putParam("delegate_url", ""); putParam("from", ""); putParam("f", ""); putParam("s", ""); } public void putParam(String key, String value){ param.put(key, value); } public String getParam(String key){ return param.get(key); } @SuppressWarnings("unchecked") public Map<String, String> getParam() { return (Map<String, String>) param.clone(); } }
-------------QQContact.java----------------
package qq; public class QQContact { private String qq; private String email; private String name; public QQContact(){} public QQContact(String qq, String email, String name){ this.qq = qq; this.email = email; this.name = name; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
----------RSAInfo.java----------------------
package qq; public class RSAInfo { private String publicKey; private String ts; private String domain; public RSAInfo(){} public RSAInfo(String publicKey, String ts, String domain){ this.publicKey = publicKey; this.ts = ts; this.domain = domain; } public String getPublicKey() { return publicKey; } public void setPublicKey(String publicKey) { this.publicKey = publicKey; } public String getTs() { return ts; } public void setTs(String ts) { this.ts = ts; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } }
-------VerifyCode.java--------------
package qq; import org.apache.commons.httpclient.Cookie; public class VerifyCode { private Cookie verifySession; private byte[] data;//verify code image public VerifyCode(){} public VerifyCode(Cookie verifySession, byte[] data){ this.verifySession = verifySession; this.data = data; } public Cookie getVerifySession() { return verifySession; } public void setVerifySession(Cookie verifySession) { this.verifySession = verifySession; } public byte[] getData() { return data; } public void setData(byte[] data) { this.data = data; } }
---------QQUtil.java-------------------
package qq; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class QQUtil { public static Pattern sidPattern = Pattern.compile("sid=(.*?)\";"); public static Pattern contactPattern = Pattern.compile("<.*?key=\"(.*?)\" addr=\"(.*?)\".*?>(.*?)</span>"); public static Pattern publicKeyPattern = Pattern.compile("PublicKey = \"(.*?)\""); public static Pattern tsPattern = Pattern.compile("PublicTs=\"(.*?)\""); public static Pattern domainPattern = Pattern.compile("action=\"(.*?\\.qq\\.com)"); public static Pattern errTypePattern = Pattern.compile("\"errtype=(.?)\""); public static String paser(String body,Pattern pattern) { String publicKey = null; Matcher matcher = pattern.matcher(body); if (matcher.find()) { publicKey = matcher.group(1); } return publicKey; } public static List<QQContact> parserQQContects(String contactsHtml) { List<QQContact> list = new ArrayList<QQContact>(); Matcher allMatcher = contactPattern.matcher(contactsHtml); while(allMatcher.find()){ String qq = allMatcher.group(1); String email = allMatcher.group(2); String name=allMatcher.group(3).replace(" ", ""); list.add(new QQContact(qq,email,name)); } return list; } }
-----------action.jsp----------
<%@ page language="java" pageEncoding="UTF-8"%> <%@page import="qq.QQContactsService"%> <%@page import="qq.AuthInfo"%> <%@page import="java.util.List"%> <%@page import="qq.QQContact"%> <% String uin = request.getParameter("uin").trim(); String pp = request.getParameter("pp").trim(); String p = request.getParameter("p").trim(); String ts = request.getParameter("ts").trim(); String starttime = request.getParameter("starttime").trim(); String verifycode = request.getParameter("verifycode").trim(); String domain = request.getParameter("domain").trim(); String cookie = request.getHeader("cookie"); System.out.println(cookie); QQContactsService service =QQContactsService.getInstance(); AuthInfo auth = new AuthInfo(); auth.putParam("uin",uin); auth.putParam("pp",pp); auth.putParam("p",p); auth.putParam("ts",ts); auth.putParam("starttime",starttime); auth.putParam("verifycode",verifycode); auth.putParam("domain",domain); auth.putParam("cookie",cookie); System.out.println(auth.getParam()); List<QQContact> list = null; try{ list = service.getQQContacts(auth); }catch(Exception e){ if(e == QQContactsService.QQ_WRONG_PWD){ out.println("密码错误"); }else if(e == QQContactsService.QQ_WRONG_VERIFY){ out.println("验证码错误"); }else if(e == QQContactsService.QQ_MANY_LOGIN_TIMES){ out.println("登录次数太多,稍后再试"); }else if(e == QQContactsService.QQ_EEROR){ out.println("服务器错误,可能代码已经失效"); }else{ out.println("服务器错误"); } return ; } if(list == null){ out.println("没有取到联系人,可能代码已经失效"); return ; } for(QQContact c:list){ out.println(c.getEmail()+" "+c.getName()+"("+c.getQq()+")<br>"); } %>
-------code.jsp----------------
<%@ page language="java" pageEncoding="UTF-8" contentType="image/jpeg"%> <%@page import="org.apache.commons.httpclient.Cookie"%> <%@page import="qq.QQContactsService"%> <%@page import="qq.VerifyCode"%> <% QQContactsService service = QQContactsService.getInstance(); VerifyCode code = service.getVerifyCode(); byte[] data = code.getData(); Cookie c = code.getVerifySession(); response.addCookie(new javax.servlet.http.Cookie(c.getName(),c.getValue())); ServletOutputStream outStream = response.getOutputStream(); outStream.write(data); out.clear(); out = pageContext.pushBody(); %>
-----------index.jsp-------------
<%@ page language="java" pageEncoding="UTF-8"%> <%@page import="qq.QQContactsService"%> <%@page import="qq.RSAInfo"%> <% QQContactsService service = QQContactsService.getInstance(); RSAInfo rsa = service.getRSAInfo(); request.setAttribute("domain", rsa.getDomain()); request.setAttribute("publicKey", rsa.getPublicKey()); request.setAttribute("ts", rsa.getTs()); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>QQ Import Contact</title> <script language="JavaScript" src="js/auth.js"></script> </head> <body> <form name="form1" action="action.jsp" onsubmit="ras()" method="post"> QQ : <input type="text" name="uin" id="uin"> <br> PWD: <input type="password" name="pp" id="pp"> <br> verify: <input type="text" name="verifycode" id="verifycode"> <img src="code.jsp"> <br> <input type="hidden" name="domain" id="domain" value="${domain}"> <input type="hidden" name="ts" id="ts"> <input type="hidden" name="starttime" id="starttime"> <input type="hidden" name="p" id="p"> <input type="submit" name="login"> <br> </form> <script type="text/javascript"> var S = function( object ) { return document.getElementById( object ); }; function ras(){ var PublicKey = "${publicKey}"; var RSA = new RSAKey(); RSA.setPublic(PublicKey, "10001"); var PublicTs="${ts}"; var Res = RSA.encrypt(S("pp").value + '\n' + PublicTs + '\n'); if (Res){ document.form1.p.value = hex2b64(Res); } var MaskValue = ""; for (var Loop = 0; Loop < S("pp").value.length; Loop++, MaskValue += "0"); document.form1.pp.value = MaskValue; document.form1.starttime.value = (new Date()).valueOf(); } </script> </body> </html>
--------auth.js--------------
var dbits; var canary = 244837814094590; var j_lm = ((canary & 16777215) == 15715070); function BigInteger(a, b, c) { if (a != null) { if ("number" == typeof a) { this.fromNumber(a, b, c); } else { if (b == null && "string" != typeof a) { this.fromString(a, 256); } else { this.fromString(a, b); } } } } function nbi() { return new BigInteger(null); } function am1(i, x, w, j, c, n) { while (--n >= 0) { var v = x * this[i++] + w[j] + c; c = Math.floor(v / 67108864); w[j++] = v & 67108863; } return c; } function am2(i, x, w, j, c, n) { var xl = x & 32767, xh = x >> 15; while (--n >= 0) { var l = this[i] & 32767; var h = this[i++] >> 15; var m = xh * l + h * xl; l = xl * l + ((m & 32767) << 15) + w[j] + (c & 1073741823); c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); w[j++] = l & 1073741823; } return c; } function am3(i, x, w, j, c, n) { var xl = x & 16383, xh = x >> 14; while (--n >= 0) { var l = this[i] & 16383; var h = this[i++] >> 14; var m = xh * l + h * xl; l = xl * l + ((m & 16383) << 14) + w[j] + c; c = (l >> 28) + (m >> 14) + xh * h; w[j++] = l & 268435455; } return c; } if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { BigInteger.prototype.am = am2; dbits = 30; } else { if (j_lm && (navigator.appName != "Netscape")) { BigInteger.prototype.am = am1; dbits = 26; } else { BigInteger.prototype.am = am3; dbits = 28; } } BigInteger.prototype.DB = dbits; BigInteger.prototype.DM = ((1 << dbits) - 1); BigInteger.prototype.DV = (1 << dbits); var BI_FP = 52; BigInteger.prototype.FV = Math.pow(2, BI_FP); BigInteger.prototype.F1 = BI_FP - dbits; BigInteger.prototype.F2 = 2 * dbits - BI_FP; var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; var BI_RC = new Array(); var rr, vv; rr = "0".charCodeAt(0); for (vv = 0; vv <= 9; ++vv) { BI_RC[rr++] = vv; } rr = "a".charCodeAt(0); for (vv = 10; vv < 36; ++vv) { BI_RC[rr++] = vv; } rr = "A".charCodeAt(0); for (vv = 10; vv < 36; ++vv) { BI_RC[rr++] = vv; } function int2char(n) { return BI_RM.charAt(n); } function intAt(s, i) { var c = BI_RC[s.charCodeAt(i)]; return (c == null) ? -1 : c; } function bnpCopyTo(r) { for (var i = this.t - 1; i >= 0; --i) { r[i] = this[i]; } r.t = this.t; r.s = this.s; } function bnpFromInt(x) { this.t = 1; this.s = (x < 0) ? -1 : 0; if (x > 0) { this[0] = x; } else { if (x < -1) { this[0] = x + DV; } else { this.t = 0; } } } function nbv(i) { var r = nbi(); r.fromInt(i); return r; } function bnpFromString(s, b) { var k; if (b == 16) { k = 4; } else { if (b == 8) { k = 3; } else { if (b == 256) { k = 8; } else { if (b == 2) { k = 1; } else { if (b == 32) { k = 5; } else { if (b == 4) { k = 2; } else { this.fromRadix(s, b); return; } } } } } } this.t = 0; this.s = 0; var i = s.length, mi = false, sh = 0; while (--i >= 0) { var x = (k == 8) ? s[i] & 255 : intAt(s, i); if (x < 0) { if (s.charAt(i) == "-") { mi = true; } continue; } mi = false; if (sh == 0) { this[this.t++] = x; } else { if (sh + k > this.DB) { this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; this[this.t++] = (x >> (this.DB - sh)); } else { this[this.t - 1] |= x << sh; } } sh += k; if (sh >= this.DB) { sh -= this.DB; } } if (k == 8 && (s[0] & 128) != 0) { this.s = -1; if (sh > 0) { this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; } } this.clamp(); if (mi) { BigInteger.ZERO.subTo(this, this); } } function bnpClamp() { var c = this.s & this.DM; while (this.t > 0 && this[this.t - 1] == c) { --this.t; } } function bnToString(b) { if (this.s < 0) { return "-" + this.negate().toString(b); } var k; if (b == 16) { k = 4; } else { if (b == 8) { k = 3; } else { if (b == 2) { k = 1; } else { if (b == 32) { k = 5; } else { if (b == 4) { k = 2; } else { return this.toRadix(b); } } } } } var km = (1 << k) - 1, d, m = false, r = "", i = this.t; var p = this.DB - (i * this.DB) % k; if (i-- > 0) { if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } while (i >= 0) { if (p < k) { d = (this[i] & ((1 << p) - 1)) << (k - p); d |= this[--i] >> (p += this.DB - k); } else { d = (this[i] >> (p -= k)) & km; if (p <= 0) { p += this.DB; --i; } } if (d > 0) { m = true; } if (m) { r += int2char(d); } } } return m ? r : "0"; } function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; } function bnAbs() { return (this.s < 0) ? this.negate() : this; } function bnCompareTo(a) { var r = this.s - a.s; if (r != 0) { return r; } var i = this.t; r = i - a.t; if (r != 0) { return r; } while (--i >= 0) { if ((r = this[i] - a[i]) != 0) { return r; } } return 0; } function nbits(x) { var r = 1, t; if ((t = x >>> 16) != 0) { x = t; r += 16; } if ((t = x >> 8) != 0) { x = t; r += 8; } if ((t = x >> 4) != 0) { x = t; r += 4; } if ((t = x >> 2) != 0) { x = t; r += 2; } if ((t = x >> 1) != 0) { x = t; r += 1; } return r; } function bnBitLength() { if (this.t <= 0) { return 0; } return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); } function bnpDLShiftTo(n, r) { var i; for (i = this.t - 1; i >= 0; --i) { r[i + n] = this[i]; } for (i = n - 1; i >= 0; --i) { r[i] = 0; } r.t = this.t + n; r.s = this.s; } function bnpDRShiftTo(n, r) { for (var i = n; i < this.t; ++i) { r[i - n] = this[i]; } r.t = Math.max(this.t - n, 0); r.s = this.s; } function bnpLShiftTo(n, r) { var bs = n % this.DB; var cbs = this.DB - bs; var bm = (1 << cbs) - 1; var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i; for (i = this.t - 1; i >= 0; --i) { r[i + ds + 1] = (this[i] >> cbs) | c; c = (this[i] & bm) << bs; } for (i = ds - 1; i >= 0; --i) { r[i] = 0; } r[ds] = c; r.t = this.t + ds + 1; r.s = this.s; r.clamp(); } function bnpRShiftTo(n, r) { r.s = this.s; var ds = Math.floor(n / this.DB); if (ds >= this.t) { r.t = 0; return; } var bs = n % this.DB; var cbs = this.DB - bs; var bm = (1 << bs) - 1; r[0] = this[ds] >> bs; for (var i = ds + 1; i < this.t; ++i) { r[i - ds - 1] |= (this[i] & bm) << cbs; r[i - ds] = this[i] >> bs; } if (bs > 0) { r[this.t - ds - 1] |= (this.s & bm) << cbs; } r.t = this.t - ds; r.clamp(); } function bnpSubTo(a, r) { var i = 0, c = 0, m = Math.min(a.t, this.t); while (i < m) { c += this[i] - a[i]; r[i++] = c & this.DM; c >>= this.DB; } if (a.t < this.t) { c -= a.s; while (i < this.t) { c += this[i]; r[i++] = c & this.DM; c >>= this.DB; } c += this.s; } else { c += this.s; while (i < a.t) { c -= a[i]; r[i++] = c & this.DM; c >>= this.DB; } c -= a.s; } r.s = (c < 0) ? -1 : 0; if (c < -1) { r[i++] = this.DV + c; } else { if (c > 0) { r[i++] = c; } } r.t = i; r.clamp(); } function bnpMultiplyTo(a, r) { var x = this.abs(), y = a.abs(); var i = x.t; r.t = i + y.t; while (--i >= 0) { r[i] = 0; } for (i = 0; i < y.t; ++i) { r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); } r.s = 0; r.clamp(); if (this.s != a.s) { BigInteger.ZERO.subTo(r, r); } } function bnpSquareTo(r) { var x = this.abs(); var i = r.t = 2 * x.t; while (--i >= 0) { r[i] = 0; } for (i = 0; i < x.t - 1; ++i) { var c = x.am(i, x[i], r, 2 * i, 0, 1); if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { r[i + x.t] -= x.DV; r[i + x.t + 1] = 1; } } if (r.t > 0) { r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); } r.s = 0; r.clamp(); } function bnpDivRemTo(m, q, r) { var pm = m.abs(); if (pm.t <= 0) { return; } var pt = this.abs(); if (pt.t < pm.t) { if (q != null) { q.fromInt(0); } if (r != null) { this.copyTo(r); } return; } if (r == null) { r = nbi(); } var y = nbi(), ts = this.s, ms = m.s; var nsh = this.DB - nbits(pm[pm.t - 1]); if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); } else { pm.copyTo(y); pt.copyTo(r); } var ys = y.t; var y0 = y[ys - 1]; if (y0 == 0) { return; } var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; var i = r.t, j = i - ys, t = (q == null) ? nbi() : q; y.dlShiftTo(j, t); if (r.compareTo(t) >= 0) { r[r.t++] = 1; r.subTo(t, r); } BigInteger.ONE.dlShiftTo(ys, t); t.subTo(y, y); while (y.t < ys) { y[y.t++] = 0; } while (--j >= 0) { var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { y.dlShiftTo(j, t); r.subTo(t, r); while (r[i] < --qd) { r.subTo(t, r); } } } if (q != null) { r.drShiftTo(ys, q); if (ts != ms) { BigInteger.ZERO.subTo(q, q); } } r.t = ys; r.clamp(); if (nsh > 0) { r.rShiftTo(nsh, r); } if (ts < 0) { BigInteger.ZERO.subTo(r, r); } } function bnMod(a) { var r = nbi(); this.abs().divRemTo(a, null, r); if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) { a.subTo(r, r); } return r; } function Classic(m) { this.m = m; } function cConvert(x) { if (x.s < 0 || x.compareTo(this.m) >= 0) { return x.mod(this.m); } else { return x; } } function cRevert(x) { return x; } function cReduce(x) { x.divRemTo(this.m, null, x); } function cMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); } function cSqrTo(x, r) { x.squareTo(r); this.reduce(r); } Classic.prototype.convert = cConvert; Classic.prototype.revert = cRevert; Classic.prototype.reduce = cReduce; Classic.prototype.mulTo = cMulTo; Classic.prototype.sqrTo = cSqrTo; function bnpInvDigit() { if (this.t < 1) { return 0; } var x = this[0]; if ((x & 1) == 0) { return 0; } var y = x & 3; y = (y * (2 - (x & 15) * y)) & 15; y = (y * (2 - (x & 255) * y)) & 255; y = (y * (2 - (((x & 65535) * y) & 65535))) & 65535; y = (y * (2 - x * y % this.DV)) % this.DV; return (y > 0) ? this.DV - y : -y; } function Montgomery(m) { this.m = m; this.mp = m.invDigit(); this.mpl = this.mp & 32767; this.mph = this.mp >> 15; this.um = (1 << (m.DB - 15)) - 1; this.mt2 = 2 * m.t; } function montConvert(x) { var r = nbi(); x.abs().dlShiftTo(this.m.t, r); r.divRemTo(this.m, null, r); if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) { this.m.subTo(r, r); } return r; } function montRevert(x) { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } function montReduce(x) { while (x.t <= this.mt2) { x[x.t++] = 0; } for (var i = 0; i < this.m.t; ++i) { var j = x[i] & 32767; var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; j = i + this.m.t; x[j] += this.m.am(0, u0, x, i, 0, this.m.t); while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } } x.clamp(); x.drShiftTo(this.m.t, x); if (x.compareTo(this.m) >= 0) { x.subTo(this.m, x); } } function montSqrTo(x, r) { x.squareTo(r); this.reduce(r); } function montMulTo(x, y, r) { x.multiplyTo(y, r); this.reduce(r); } Montgomery.prototype.convert = montConvert; Montgomery.prototype.revert = montRevert; Montgomery.prototype.reduce = montReduce; Montgomery.prototype.mulTo = montMulTo; Montgomery.prototype.sqrTo = montSqrTo; function bnpIsEven() { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; } function bnpExp(e, z) { if (e > 4294967295 || e < 1) { return BigInteger.ONE; } var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; g.copyTo(r); while (--i >= 0) { z.sqrTo(r, r2); if ((e & (1 << i)) > 0) { z.mulTo(r2, g, r); } else { var t = r; r = r2; r2 = t; } } return z.revert(r); } function bnModPowInt(e, m) { var z; if (e < 256 || m.isEven()) { z = new Classic(m); } else { z = new Montgomery(m); } return this.exp(e, z); } BigInteger.prototype.copyTo = bnpCopyTo; BigInteger.prototype.fromInt = bnpFromInt; BigInteger.prototype.fromString = bnpFromString; BigInteger.prototype.clamp = bnpClamp; BigInteger.prototype.dlShiftTo = bnpDLShiftTo; BigInteger.prototype.drShiftTo = bnpDRShiftTo; BigInteger.prototype.lShiftTo = bnpLShiftTo; BigInteger.prototype.rShiftTo = bnpRShiftTo; BigInteger.prototype.subTo = bnpSubTo; BigInteger.prototype.multiplyTo = bnpMultiplyTo; BigInteger.prototype.squareTo = bnpSquareTo; BigInteger.prototype.divRemTo = bnpDivRemTo; BigInteger.prototype.invDigit = bnpInvDigit; BigInteger.prototype.isEven = bnpIsEven; BigInteger.prototype.exp = bnpExp; BigInteger.prototype.toString = bnToString; BigInteger.prototype.negate = bnNegate; BigInteger.prototype.abs = bnAbs; BigInteger.prototype.compareTo = bnCompareTo; BigInteger.prototype.bitLength = bnBitLength; BigInteger.prototype.mod = bnMod; BigInteger.prototype.modPowInt = bnModPowInt; BigInteger.ZERO = nbv(0); BigInteger.ONE = nbv(1); function Arcfour() { this.i = 0; this.j = 0; this.S = new Array(); } function ARC4init(key) { var i, j, t; for (i = 0; i < 256; ++i) { this.S[i] = i; } j = 0; for (i = 0; i < 256; ++i) { j = (j + this.S[i] + key[i % key.length]) & 255; t = this.S[i]; this.S[i] = this.S[j]; this.S[j] = t; } this.i = 0; this.j = 0; } function ARC4next() { var t; this.i = (this.i + 1) & 255; this.j = (this.j + this.S[this.i]) & 255; t = this.S[this.i]; this.S[this.i] = this.S[this.j]; this.S[this.j] = t; return this.S[(t + this.S[this.i]) & 255]; } Arcfour.prototype.init = ARC4init; Arcfour.prototype.next = ARC4next; function prng_newstate() { return new Arcfour(); } var rng_psize = 256; var rng_state; var rng_pool; var rng_pptr; function rng_seed_int(x) { rng_pool[rng_pptr++] ^= x & 255; rng_pool[rng_pptr++] ^= (x >> 8) & 255; rng_pool[rng_pptr++] ^= (x >> 16) & 255; rng_pool[rng_pptr++] ^= (x >> 24) & 255; if (rng_pptr >= rng_psize) { rng_pptr -= rng_psize; } } function rng_seed_time() { rng_seed_int(new Date().getTime()); } if (rng_pool == null) { rng_pool = new Array(); rng_pptr = 0; var t; if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { var z = window.crypto.random(32); for (t = 0; t < z.length; ++t) { rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; } } while (rng_pptr < rng_psize) { t = Math.floor(65536 * Math.random()); rng_pool[rng_pptr++] = t >>> 8; rng_pool[rng_pptr++] = t & 255; } rng_pptr = 0; rng_seed_time(); } function rng_get_byte() { if (rng_state == null) { rng_seed_time(); rng_state = prng_newstate(); rng_state.init(rng_pool); for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) { rng_pool[rng_pptr] = 0; } rng_pptr = 0; } return rng_state.next(); } function rng_get_bytes(ba) { var i; for (i = 0; i < ba.length; ++i) { ba[i] = rng_get_byte(); } } function SecureRandom() { } SecureRandom.prototype.nextBytes = rng_get_bytes; function parseBigInt(str, r) { return new BigInteger(str, r); } function linebrk(s, n) { var ret = ""; var i = 0; while (i + n < s.length) { ret += s.substring(i, i + n) + "\n"; i += n; } return ret + s.substring(i, s.length); } function byte2Hex(b) { if (b < 16) { return "0" + b.toString(16); } else { return b.toString(16); } } function pkcs1pad2(s, n) { if (n < s.length + 11) { alert("Message too long for RSA"); return null; } var ba = new Array(); var i = s.length - 1; while (i >= 0 && n > 0) { ba[--n] = s.charCodeAt(i--); } ba[--n] = 0; var rng = new SecureRandom(); var x = new Array(); while (n > 2) { x[0] = 0; while (x[0] == 0) { rng.nextBytes(x); } ba[--n] = x[0]; } ba[--n] = 2; ba[--n] = 0; return new BigInteger(ba); } function RSAKey() { this.n = null; this.e = 0; this.d = null; this.p = null; this.q = null; this.dmp1 = null; this.dmq1 = null; this.coeff = null; } function RSASetPublic(N, E) { if (N != null && E != null && N.length > 0 && E.length > 0) { this.n = parseBigInt(N, 16); this.e = parseInt(E, 16); } else { alert("Invalid RSA public key"); } } function RSADoPublic(x) { return x.modPowInt(this.e, this.n); } function RSAEncrypt(text) { var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3); if (m == null) { return null; } var c = this.doPublic(m); if (c == null) { return null; } var h = c.toString(16); if ((h.length & 1) == 0) { return h; } else { return "0" + h; } } RSAKey.prototype.doPublic = RSADoPublic; RSAKey.prototype.setPublic = RSASetPublic; RSAKey.prototype.encrypt = RSAEncrypt; var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var b64pad = "="; function hex2b64(h) { var i; var c; var ret = ""; for (i = 0; i + 3 <= h.length; i += 3) { c = parseInt(h.substring(i, i + 3), 16); ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); } if (i + 1 == h.length) { c = parseInt(h.substring(i, i + 1), 16); ret += b64map.charAt(c << 2); } else { if (i + 2 == h.length) { c = parseInt(h.substring(i, i + 2), 16); ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); } } while ((ret.length & 3) > 0) { ret += b64pad; } return ret; } function b64tohex(s) { var ret = ""; var i; var k = 0; var slop; for (i = 0; i < s.length; ++i) { if (s.charAt(i) == b64pad) { break; } v = b64map.indexOf(s.charAt(i)); if (v < 0) { continue; } if (k == 0) { ret += int2char(v >> 2); slop = v & 3; k = 1; } else { if (k == 1) { ret += int2char((slop << 2) | (v >> 4)); slop = v & 15; k = 2; } else { if (k == 2) { ret += int2char(slop); ret += int2char(v >> 2); slop = v & 3; k = 3; } else { ret += int2char((slop << 2) | (v >> 4)); ret += int2char(v & 15); k = 0; } } } } if (k == 1) { ret += int2char(slop << 2); } return ret; } function b64toBA(s) { var h = b64tohex(s); var i; var a = new Array(); for (i = 0; 2 * i < h.length; ++i) { a[i] = parseInt(h.substring(2 * i, 2 * i + 2), 16); } return a; }
- qq-ImportContect.rar (769.6 KB)
- 下载次数: 103
评论
验证码返回时,QQ服务器多加了一个Cookie:authimgs_id=0,加上就好了
你好 请问是加在什么地方哦,找了好几天了 QQ联系人还是没法导入,有点急 。。谢谢楼主了
代码已经更新放到附件中了,你试试能不能用
用了附件里的代码 还是提示验证码错误哦。。。
验证码返回时,QQ服务器多加了一个Cookie:authimgs_id=0,加上就好了
你好 请问是加在什么地方哦,找了好几天了 QQ联系人还是没法导入,有点急 。。谢谢楼主了
代码已经更新放到附件中了,你试试能不能用
验证码返回时,QQ服务器多加了一个Cookie:authimgs_id=0,加上就好了
你好 请问是加在什么地方哦,找了好几天了 QQ联系人还是没法导入,有点急 。。谢谢楼主了
验证码返回时,QQ服务器多加了一个Cookie:authimgs_id=0,加上就好了
全世界都在学
相关推荐
在描述中提到的"一键导入QQ好友mail",意味着用户不再需要手动输入每个QQ好友的邮箱地址,只需通过授权插件访问QQ账号,就能自动获取并邀请QQ联系人加入UCHome。这大大提升了用户体验,减少了操作步骤,增加了社区的...
这可能需要下载和安装一个特定的插件,以便从QQ导入联系人到微信。 5. **查看好友列表**:插件安装完成后,你会进入一个新的界面,显示你的QQ好友列表。在这里,你可以看到哪些朋友已经使用微信,哪些还没有。 6. ...
然而,对于QQ用户,由于腾讯的保护措施,直接将QQ好友导入旺旺并不容易。作者提供了一种曲线救国的方法:通过添加QQ邮箱好友来间接邀请QQ上的朋友。具体步骤如下: 1. 输入QQ邮箱账号和密码,旺旺会显示出使用该...
**方法概述**:通过微信与QQ账号的绑定,利用“添加朋友”中的“添加QQ好友”功能来邀请已绑定QQ的用户成为微信好友。当前大约有一半的微信用户绑定了QQ账号,发送好友请求后,约有30%的用户会同意。 **拓展技巧**...
- 使用QQ手机助手等工具批量导入电话号码; - 主动添加从事特定行业的人员(如保险销售、房地产中介等),这类人群往往具有较高的消费能力; - 针对特定职业群体展开推广活动,提高转化率。 #### 方法4:实体店...
- **建立联系机制**:与团购导航网站合作,定期提交团购信息。 - **扩大关键词范围**:吸引更多周边城市流量。 - **加强微博营销**:利用微博平台提高品牌曝光。 - **设立QQ群**:吸引和留住顾客。 - **线下...
- **联系方式**:提供联系人姓名、电话号码和QQ号等信息,便于潜在客户咨询和获取更多信息。 通过以上内容可以看出,O2O网上超市系统不仅具有丰富的功能模块,而且充分考虑到了本地化服务的特点和需求,能够有效地...
为了快速建立微信好友库,我们可以从现有的社交网络出发,如通过扫一扫添加熟人、导入通讯录和QQ联系人。更有效的方法是建立或加入微信群,例如基于共同兴趣、邻里关系或特定需求(如拼车群、业主群)的群组。在群内...
通过即时通讯系统,可以很方便的邀请好友加入到视频会议中。 云台支持:支持各类主流云台,可以远程控制云台运动。 虚拟会议中心:单个服务器支持多个虚拟视频会议。所有的会议都可以进行,彼此之间相互独立互不干扰...
通过即时通讯系统,可以很方便的邀请好友加入到视频会议中。 云台支持:支持各类主流云台,可以远程控制云台运动。 虚拟会议中心:单个服务器支持多个虚拟视频会议。所有的会议都可以进行,彼此之间相互独立互不干扰...
最近总遇到网友反应,网狐荣耀版房卡游戏,在创建房间后,邀请好友等操作后。好友点击分享链接没反应或是空白,或是出错。这样的问题,在进行代码修改和相应的设置后,问题解决。 二十二、网狐荣耀版启动游戏时提示...
8. UI设计:提供友好、直观的用户界面,包括聊天界面、联系人列表、消息通知等。 Android Studio集成与测试 本项目中的`openfire-android.zip`文件包含了Android客户端的源代码,可以在Android Studio中导入并进行...