欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java pdu短信解码全面解析

程序员文章站 2024-03-12 18:22:50
长短信未验证 有兴趣的可以试试 根据python的方法改写的 /** * pdu短信解析 * * * @param pdupayload * @ret...

长短信未验证 有兴趣的可以试试

根据python的方法改写的

/**
* pdu短信解析
*
*
* @param pdupayload
* @return
*/
public static string retrievesmsinfo(byte[] pdupayload) throws unsupportedencodingexception {
int startpos = 3;
//#originator address
int mrp_oa_len = pdupayload[startpos];
byte[] mrp_oa = new byte[mrp_oa_len];
system.arraycopy(pdupayload, startpos + 1, mrp_oa, 0, mrp_oa_len);
startpos = startpos + 1 + mrp_oa_len;
int mtpdu_len = pdupayload[startpos];
//#bit no. 7 6 5 4 3 2 1 0 
//#uplink tp-rp tp-udhi tp-spr tp-vpf tp-rd tp-mti 
//#downlink tp-rp tp-udhi tp-sri tp-mms tp-mti 
byte tp_header = pdupayload[startpos + 1];
byte tp_msg_ref = pdupayload[startpos + 2];
int tp_udhi = (tp_header >> 6) & 1; //#短信内容是否包含协议头信息,0 不包含, 1 包含(长短信,push短信)
int tp_vpf = (tp_header >> 3) & 3; //#是否包含有效期字节,0 不包含, 其他 包含 
// #00表示无有效期,tp-vp设置为00。 
// #10表示相对格式,tp-vp占用1字节。 
// #01表示增加格式,tp-vp占用7字节。 
// #11表示绝对格式,tp-vp占用7字节
int tp_mms = (tp_header >> 2) & 1;//# tp-mms(tp-more-message-to-send):1 短信中心没有更多的消息发送
startpos = startpos + 3;
//#对方号码
byte smsnumberlen = pdupayload[startpos];
int mtp_da_len = (smsnumberlen + 1) / 2 + 1;
byte[] mtp_da = new byte[mtp_da_len];
system.arraycopy(pdupayload, startpos + 1, mtp_da, 0, mtp_da_len * 1);
byte mtp_da_format = mtp_da[0];
byte[] smsnumberraw = new byte[mtp_da.length - 1];
system.arraycopy(mtp_da, 1, smsnumberraw, 0, mtp_da.length - 1);
string smsnumber = "";
int j = 0;
for (int i = 0; i < smsnumberlen; i++) {
if ((i & 1) == 0) {
smsnumber = smsnumber + (int) (smsnumberraw[j] & 0xf);
} else {
smsnumber = smsnumber + (int) ((smsnumberraw[j] & 0x0ff) >> 4);
j++;
}
}
startpos = startpos + 1 + mtp_da_len;
byte mtp_pid = pdupayload[startpos];
byte mtp_dcs = pdupayload[startpos + 1];//#“00”表示使用7位编码,设置为“02”使用8位编码,设置为“08”使用ucs2编码。
startpos = startpos + 2;
if (tp_vpf == 2) {
startpos = startpos + 1;
} else if (tp_vpf == 1 || tp_vpf == 3) {
startpos = startpos + 7;
}
//# 长短信:内容前面需要增加6个字段 
//# 1、 字节一:包头长度,固定填写0x05; 
//# 2、 字节二:包头类型标识,固定填写0x00,表示长短信; 
//# 3、 字节三:子包长度,固定填写0x03,表示后面三个字节的长度; 
//# 4、 字节四到字节六:包内容: 
//# a) 字节四:长消息参考号,每个sp给每个用户发送的每条参考号都应该不同,可以从0开始,每次加1,最大255,便于同一个终端对同一个sp的消息的不同的长短信进行识别; 
//# b) 字节五:本条长消息的的总消息数,从1到255,一般取值应该大于2; 
//# c) 字节六:本条消息在长消息中的位置或序号,从1到255,第一条为1,第二条为2,最后一条等于第四字节的值。 
//# 例子: 
//# 05 00 03 00 02 01 
//# 05 00 03 00 02 02 
int smspayloadlen = pdupayload[startpos];
startpos = startpos + 1;
string smscontent = "";
if (tp_udhi == 1) {
//#长短信--未验证 可能需要转无符号
byte smstotal = pdupayload[startpos + 4];
byte smsidx = pdupayload[startpos + 5];
startpos = startpos + 6;
smscontent = "长短信(" + bytetohex(smsidx) + "/" + bytetohex(smstotal) + "}";
smscontent = new string(smscontent.getbytes("gbk"));
smspayloadlen = smspayloadlen - 6;
}
byte[] smspayload = new byte[pdupayload.length - startpos];
system.arraycopy(pdupayload, startpos, smspayload, 0, pdupayload.length - startpos);
if (mtp_dcs == 0) {
//#7位编码--已验证
smspayloadlen = (smspayloadlen * 7 + 7) / 8;
int asciidata = 0;
int lastbyteremain = 0;
for (int i = 0; i < smspayloadlen; i++) {
asciidata = asciidata + ((smspayload[i] & 0x0ff) << lastbyteremain);
smscontent = smscontent + (char) ((asciidata & 0x0ff) & 0x7f);
asciidata = asciidata >> 7;
lastbyteremain = lastbyteremain + 1;
if (lastbyteremain >= 7) {
smscontent = smscontent + (char) ((asciidata & 0x0ff) & 0x7f);
asciidata = asciidata >> 7;
lastbyteremain = lastbyteremain - 7;
}
}
} else if (mtp_dcs == 8) {
//# ucs-2 --已验证 可正常解析
for (int i = 0; i < smspayloadlen; i = i + 2) {
int cc1 = (smspayload[i] & 0x0ff) * 256;
int cc2 = smspayload[i + 1] & 0x0ff;
smscontent = smscontent + (char) (cc1 + cc2);
}
}
return smsnumber + ":" + smscontent;
}

以上所述是小编给大家介绍的java pdu短信解码全面解析,希望对大家有所帮助