java 融合飞信_java版飞信协议实现

packagemyFetion;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStreamWriter;importjava.io.UnsupportedEncodingException;importjava.net.HttpURLConnection;importjava.net.URL;importjava.nio.ByteBuffer;importjava.security.MessageDigest;importjava.util.HashMap;importjava.util.Iterator;importjava.util.List;importjava.util.Map;importjava.util.UUID;importjava.util.Map.Entry;importjava.util.regex.Matcher;importjava.util.regex.Pattern;importorg.apache.commons.codec.binary.Hex;importorg.dom4j.Attribute;importorg.dom4j.Document;importorg.dom4j.DocumentHelper;importorg.dom4j.Element;public classlibFx {//[start] 变量定义

private static final String SIP_M = "M fetion.com.cn SIP-C/2.0";private static final String SIP_S = "S fetion.com.cn SIP-C/2.0";private static String URL_SD = "http://221.176.31.42/ht/sd.aspx";private static String URL_LOGIN = "https://uid.fetion.com.cn/ssiportal/SSIAppSignIn.aspx";private static String URL_CONFIG = "http://nav.fetion.com.cn/nav/getsystemconfig.aspx";private intcall, seq;privateString username, password;privateString ssic, sid, guid, domain, uri;private HashMap allBuddys = new HashMap();//[end]

private classresResult {intstatus;

Map>header;

String response;

}public classbuddyInfo {

String uri;

String mobile;

String localname;

String nickname;

String buddytype;

String displayname;

}publiclibFx(String username, String password) {this.username =username;this.password =password;

}public voidgetSystemConfig() {

String data= "

data+= "\" />";

data+= "";

data+= "

";

resResult res= httpRequest(URL_CONFIG, data, null);try{

String[] resSplit= res.response.split("\r\n");

String xmlData= resSplit[0];

Document xml=DocumentHelper.parseText(xmlData);

Element httptunnel= (Element) xml.selectObject("/config/servers/http-tunnel");

URL_SD=httptunnel.getStringValue();

Element ssiappsignin= (Element) xml.selectObject("/config/servers/ssi-app-sign-in");

URL_LOGIN=ssiappsignin.getStringValue();

}catch(Exception ex) {

System.out.println(ex.getMessage());

}

}//[start] 登录,注册到服务器,退出

publicString Login() {

String debugMsg= "";try{

String data= "mobileno=" + username + "&pwd=" + password + "";

resResult res= httpRequest(URL_LOGIN, data, null);if (res == null) {

debugMsg= "login error";returndebugMsg;

}

String header=res.header.values().toString();

Pattern ssicPattern= Pattern.compile("ssic=(.*?);");

Matcher matcher=ssicPattern.matcher(header);if(matcher.find()) {

ssic= matcher.group(1);

}

Document document=DocumentHelper.parseText(res.response);

Element root=document.getRootElement();

Element user= root.element("user");//示例:

uri = user.attribute("uri").getValue();int a = uri.indexOf("@");int b = uri.indexOf(";");

sid= uri.substring(4, a);

domain= uri.substring(a + 1, b);

}catch(Exception ex) {

debugMsg+=ex.getMessage();returndebugMsg;

}return "OK" +debugMsg;

}publicString Register() {

String debugMsg= "";

String arg= "";

arg+= "";

arg+= "";

arg+= "";

String response= null, nonce = null;

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "1 R");

String msg= createSipData("R fetion.com.cn SIP-C/2.0", fields, arg) + "SIPP";//发送请求

response = sendRequest(nextUrl("i"), msg).response;

response= sendRequest(nextUrl("s"), "SIPP").response;

Pattern noncePattern= Pattern.compile("nonce=\"(\\w+)\"");

Matcher m=noncePattern.matcher(response);if(m.find()) {

nonce= m.group(1);

}else{return "not find noce!" +response;

}

String salt= "777A6D03";

String cnonce=calc_cnonce();

String calcResponse=calc_response(nonce, cnonce);

String strA= "Digest algorithm=\"SHA1-sess\",response=\"" + calcResponse + "\",";

strA+= "cnonce=\"" + cnonce + "\",salt=\"" + salt + "\",ssic=\"" + ssic + "\"";

fields= new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "2 R");

fields.put("A", strA);

msg= createSipData("R fetion.com.cn SIP-C/2.0", fields, arg) + "SIPP";//发送请求

response = sendRequest(nextUrl("s"), msg).response;

response= sendRequest(nextUrl("s"), "SIPP").response;if (response == null) {return "not 2R";

}return "OK" +debugMsg;

}public booleanlogout() {

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", "1");

fields.put("Q", "2 R");

fields.put("X", "0");

String msg= createSipData("R fetion.com.cn SIP-C/2.0", fields, null) + "SIPP";

String response= sendRequest(nextUrl("s"), msg).response;

System.out.println("退出:" +response);if (response == null || response.equals("")) {return false;

}return true;

}//[end]//[start] 相关算法

privateString nextCall() {

call+= 1;returnString.valueOf(call);

}privateString nextUrl(String t) {

seq++;

System.out.println(URL_SD+ "?t=" + t + "&i=" +seq);return new StringBuffer(URL_SD).append("?t=").append(t).append("&i=").append(seq).toString();

}privateString calc_cnonce() {

MessageDigest md5= null;

String md5Str= null;try{

md5= MessageDigest.getInstance("MD5");

md5.update(UUID.randomUUID().toString().getBytes("UTF-8"));

md5Str= newString(Hex.encodeHex(md5.digest())).toUpperCase();

}catch(Exception e) {return null;

}returnmd5Str;

}privateString calc_response(String nonce, String cnonce) {

String temp= ":";

String strTemp= "REGISTER";char[] saltChars = { 0x77, 0x7A, 0x6D, 0x03};

String salt=String.valueOf(saltChars);

String h3= null;try{int sidLength = sid.getBytes("UTF-8").length;int domainLength = domain.getBytes("UTF-8").length;int nonceLength = nonce.getBytes("UTF-8").length;int tempLength = temp.getBytes("UTF-8").length;int strTempLength = strTemp.getBytes("UTF-8").length;int cnonceLength = cnonce.getBytes("UTF-8").length;

ByteBuffer buf= null;//晕,这部有点多余可以省略,就是把原来加密过的字符串转成字节//byte[] decode = Hex.decodeHex(binstr.toUpperCase().toCharArray());

MessageDigest sha1= MessageDigest.getInstance("SHA-1");//密码使用SHA-1加密

sha1 = MessageDigest.getInstance("SHA-1");

sha1.update(password.getBytes("UTF-8"));byte[] src =sha1.digest();//加密后把{ 0x77, 0x7A, 0x6D, 0x03 }这四个字符加上用SHA-1加密过的密码

buf = ByteBuffer.allocate(src.length + salt.getBytes("UTF-8").length);

buf.put(salt.getBytes("UTF-8"));

buf.put(src);

buf.flip();

sha1.update(buf);

buf.clear();//然后再把相加过的`字节数组`用SHA-1加密

byte[] decode =sha1.digest();//用SHA-1加密```形式如 sid:domain:decode

buf = ByteBuffer.allocate(sidLength + domainLength + decode.length + (tempLength * 2));

buf.put(sid.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(domain.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(decode);

buf.flip();

sha1.update(buf);byte[] keyBytes =sha1.digest();//用MD5加密```形式如 key:nonce:cnonce 上面生成的就是key 生成h1

MessageDigest md5 = MessageDigest.getInstance("MD5");

buf= ByteBuffer.allocate(keyBytes.length + nonceLength + cnonceLength + (tempLength * 2));

buf.put(keyBytes);

buf.put(temp.getBytes("UTF-8"));

buf.put(nonce.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(cnonce.getBytes("UTF-8"));

buf.flip();

md5.update(buf);

buf.clear();

String h1= newString(Hex.encodeHex(md5.digest())).toUpperCase();//用MD5加密```形式如 REGISTER:sid 生成h2

buf = ByteBuffer.allocate(sidLength + strTempLength +tempLength);

buf.put(strTemp.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(sid.getBytes("UTF-8"));

buf.flip();

md5.update(buf);

buf.clear();

String h2= newString(Hex.encodeHex(md5.digest())).toUpperCase();//用MD5加密```形式如 h1:nonce:h2 生成h2

buf = ByteBuffer.allocate(h1.getBytes("UTF-8").length + nonceLength + h2.getBytes("UTF-8").length + (tempLength * 2));

buf.put(h1.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(nonce.getBytes("UTF-8"));

buf.put(temp.getBytes("UTF-8"));

buf.put(h2.getBytes("UTF-8"));

buf.flip();

md5.update(buf);

buf.clear();

h3= newString(Hex.encodeHex(md5.digest())).toUpperCase();

}catch(Exception e) {

e.printStackTrace();

}returnh3;

}private String createSipData(String invite, HashMapfields, String arg) {

StringBuffer sip= new StringBuffer(invite).append("\r\n");for (Map.Entryentry : fields.entrySet()) {

sip.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");

}if (arg != null) {try{

sip.append("L: ").append(arg.getBytes("UTF-8").length).append("\r\n\r\n").append(arg);

}catch(UnsupportedEncodingException e) {return null;

}

}returnsip.toString();

}//[end]//[start] http请求

private resResult httpRequest(String strUrl, String data, Mapheads) {

resResult res= newresResult();

URL url= null;

HttpURLConnection conn= null;for (int i = 0; i < 10; i++) {//如果请求失败,则重试5次

try{

url= newURL(strUrl);

conn=(HttpURLConnection) url.openConnection();

conn.setDoOutput(true);//设置输出

conn.setUseCaches(false);//不使用缓存

conn.setRequestMethod("POST");//循环设置请求头部,比如cookie

if (heads != null) {for (Entryentry : heads.entrySet())

conn.setRequestProperty(entry.getKey(), entry.getValue());

}

OutputStreamWriter out= newOutputStreamWriter(conn.getOutputStream());

out.write(data);//写入请求(POST)数据

out.flush();

out.close();

InputStream in=conn.getInputStream();

BufferedReader br= new BufferedReader(new InputStreamReader(in, "utf-8"));

String line= "", response = "";while ((line = br.readLine()) != null) {

response+= line + "\r\n";

}

Map> resHeads =conn.getHeaderFields();

res.status=conn.getResponseCode();

System.out.println("conn_code:" +res.status);

res.response=response;

res.header=resHeads;

}catch(Exception e) {

System.out.println(e.getMessage());

}finally{if (conn != null)

conn.disconnect();

}if (res.status == 200) {break;//重试若干次,当返回200则跳出

}try{

Thread.sleep(1000);

}catch(InterruptedException e) {

}

}returnres;

}privateresResult sendRequest(String strUrl, String data) {if (guid == null) {

guid=UUID.randomUUID().toString();

}

resResult res= newresResult();try{

Map cookies = new HashMap();

cookies.put("User-Agent", "IIC2.0/PC 3.5.2540");

cookies.put("Cookie", "ssic=" +ssic);

cookies.put("Content-Type", "application/oct-stream");

cookies.put("Pragma", "xz4BBcV" +guid);//StringRequestEntity m_data = new StringRequestEntity(data, "text/xml", "utf-8");

res =httpRequest(strUrl, data, cookies);

}catch(Exception e) {return null;

}returnres;

}//[end]///以下是飞信应用API

public HashMapgetContactsInfo() {

allBuddys=getContactsList();

StringBuffer arg= new StringBuffer("");for (Entrybuddy : allBuddys.entrySet()) {

arg.append("");

}

arg.append("");

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "1 S");

fields.put("N", "GetContactsInfo");

String msg= createSipData(SIP_S, fields, arg.toString()) + "SIPP";try{

sendRequest(nextUrl("s"), msg);

Thread.sleep(2000);

String response= sendRequest(nextUrl("s"), "SIPP").response;

String[] resSplit= response.split("\r\n\r\n");

String xmlData= resSplit[1].replace("SIPP", "");

Document xml=DocumentHelper.parseText(xmlData);

List contacts= xml.selectNodes("/results/contacts/contact");

Iterator itc=contacts.iterator();while(itc.hasNext()) {

Element elt=(Element) itc.next();

Attribute uri= elt.attribute("uri");

buddyInfo buddy=allBuddys.get(uri.getStringValue());

Element personal= elt.element("personal");

Attribute mobile= personal.attribute("mobile-no");

Attribute nickname= personal.attribute("nickname");

buddy.mobile=mobile.getStringValue();

buddy.nickname=nickname.getStringValue();

buddy.buddytype= "mobile";

String display=buddy.localname;if (display.equals(""))

display=buddy.nickname;if (display.equals(""))

display=buddy.mobile;if (display.equals(""))

display= "猪头啦";

buddy.displayname=display;

}

}catch(Exception ex) {

}returnallBuddys;

}private HashMapgetContactsList() {

String arg= "";

arg+= "";

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "1 S");

fields.put("N", "GetContactList");

String msg= createSipData(SIP_S, fields, arg) + "SIPP";

sendRequest(nextUrl("s"), msg);

String response= sendRequest(nextUrl("s"), "SIPP").response;

HashMap lstbuddys = new HashMap();try{

String[] resSplit= response.split("\r\n\r\n");

String xmlData= resSplit[1].replace("SIPP", "");

Document xml=DocumentHelper.parseText(xmlData);//获取飞信好友

List buddys = xml.selectNodes("/results/contacts/buddies/buddy");

Iterator itb=buddys.iterator();while(itb.hasNext()) {

Element elt=(Element) itb.next();

Attribute uri= elt.attribute("uri");

Attribute localname= elt.attribute("local-name");

buddyInfo buddy= newbuddyInfo();

buddy.uri=uri.getStringValue();

buddy.localname=localname.getStringValue();

buddy.buddytype= "buddy";

lstbuddys.put(buddy.uri, buddy);

}//获取手机好友

List mobiles = xml.selectNodes("/results/contacts/mobile-buddies/mobile-buddy");

Iterator itm=mobiles.iterator();while(itm.hasNext()) {

Element elt=(Element) itm.next();

Attribute uri= elt.attribute("uri");

Attribute localname= elt.attribute("local-name");

buddyInfo buddy= newbuddyInfo();

buddy.uri=uri.getStringValue();

buddy.localname=localname.getStringValue();

buddy.buddytype= "mobile";

lstbuddys.put(buddy.uri, buddy);

}

}catch(Exception ex) {

}returnlstbuddys;

}privateString getUri(String mobile) {if (allBuddys.entrySet().size() == 0)

getContactsInfo();for (Entryentry : allBuddys.entrySet()) {if(entry.getValue().mobile.equals(mobile))returnentry.getKey();

}return null;

}public booleansendCatSms(String content) {return sendCatSms(null, content);

}public booleansendCatSms(String to, String content) {//T试了好像只能是标准的sip地址,不知道有没有什么办法能换成手机号,sip:57358215@fetion.com.cn;p=4009中4009的计算公式://13开头的手机号//p=手机号码前6位 - 134099//15开头的手机号//p=手机号码前6位 - 153099//String toMobile = buddys.get(to);//if (toMobile == null || "".equals(toMobile))//return false;

String sendto=to;if (!to.startsWith("sip"))

sendto=getUri(to);if (sendto == null)return false;

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "1 M");

fields.put("T", to == null ?uri : sendto);

fields.put("N", "SendCatSMS");

String msg= createSipData(SIP_M, fields, content) + "SIPP";

sendRequest(nextUrl("s"), msg);

String response= sendRequest(nextUrl("s"), "SIPP").response;if (response.indexOf("Send SMS OK") > 0)return true;else

return false;

}public booleansendSms(String to, String content) {int len =content.length();

HashMap fields = new HashMap();

fields.put("F", sid);

fields.put("I", nextCall());

fields.put("Q", "0 M");

fields.put("T", uri);

fields.put("C", "text/html-fragment");

fields.put("K", "SaveHistory");

fields.put("L", String.valueOf(len));

String msg= createSipData(SIP_M, fields, content) + "SIPP";

String response= sendRequest(nextUrl("s"), msg).response;

response= sendRequest(nextUrl("s"), "SIPP").response;if (response.indexOf("Send SMS OK") > 0)return true;else

return false;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值