Java pdu 短信解码全面解析
这里有新鲜出炉的 Java 并发编程示例, 程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
本文是根据 python 的方法改写的 pdu 短信解码, 非常不错, 代码简单易懂具有参考借鉴价值, 感兴趣的朋友一起看看吧
长短信未验证 有兴趣的可以试试
根据 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;
- }
来源: http://www.phperz.com/article/18/0212/359614.html