java pdu短信解碼
長短信未驗證 有興趣的可以試試
根據python的方法改寫的

1 /**
2 * PDU短信解析
3 *
4 *
5 * @param pduPayload
6 * @return
7 */
8 public static String retrieveSMSInfo(byte[] pduPayload) throws UnsupportedEncodingException {
9
10 int startPos = 3;
11 //#Originator address
12 int mRP_OA_len = pduPayload[startPos];
13 byte[] mRP_OA = new byte[mRP_OA_len];
14 System.arraycopy(pduPayload, startPos + 1, mRP_OA, 0, mRP_OA_len);
15 startPos = startPos + 1 + mRP_OA_len;
16 int mTPDU_len = pduPayload[startPos];
17 //#BIT No. 7 6 5 4 3 2 1 0
18 //#uplink TP-RP TP-UDHI TP-SPR TP-VPF TP-RD TP-MTI
19 //#downlink TP-RP TP-UDHI TP-SRI TP-MMS TP-MTI
20 byte TP_Header = pduPayload[startPos + 1];
21 byte TP_Msg_Ref = pduPayload[startPos + 2];
22 int TP_UDHI = (TP_Header >> 6) & 1; //#短信內容是否包含協議頭信息,0 不包含, 1 包含(長短信,push短信)
23 int TP_VPF = (TP_Header >> 3) & 3; //#是否包含有效期字節,0 不包含, 其他 包含
24 // #00表示無有效期,TP-VP設置為00。
25 // #10表示相對格式,TP-VP占用1字節。
26 // #01表示增加格式,TP-VP占用7字節。
27 // #11表示絕對格式,TP-VP占用7字節
28 int TP_MMS = (TP_Header >> 2) & 1;//# TP-MMS(TP-More-Message-to-Send):1 短信中心沒有更多的消息發送
29 startPos = startPos + 3;
30 //#對方號碼
31 byte smsNumberLen = pduPayload[startPos];
32 int mTP_DA_len = (smsNumberLen + 1) / 2 + 1;
33 byte[] mTP_DA = new byte[mTP_DA_len];
34 System.arraycopy(pduPayload, startPos + 1, mTP_DA, 0, mTP_DA_len * 1);
35 byte mTP_DA_format = mTP_DA[0];
36 byte[] smsNumberRaw = new byte[mTP_DA.length - 1];
37 System.arraycopy(mTP_DA, 1, smsNumberRaw, 0, mTP_DA.length - 1);
38 String smsNumber = "";
39 int j = 0;
40 for (int i = 0; i < smsNumberLen; i++) {
41
42 if ((i & 1) == 0) {
43 smsNumber = smsNumber + (int) (smsNumberRaw[j] & 0xF);
44 } else {
45 smsNumber = smsNumber + (int) ((smsNumberRaw[j] & 0x0FF) >> 4);
46 j++;
47 }
48 }
49 startPos = startPos + 1 + mTP_DA_len;
50
51 byte mTP_PID = pduPayload[startPos];
52 byte mTP_DCS = pduPayload[startPos + 1];//#“00”表示使用7位編碼,設置為“02”使用8位編碼,設置為“08”使用UCS2編碼。
53
54 startPos = startPos + 2;
55 if (TP_VPF == 2) {
56 startPos = startPos + 1;
57 } else if (TP_VPF == 1 || TP_VPF == 3) {
58 startPos = startPos + 7;
59 }
60 //# 長短信:內容前面需要增加6個字段
61 //# 1、 字節一:包頭長度,固定填寫0x05;
62 //# 2、 字節二:包頭類型標識,固定填寫0x00,表示長短信;
63 //# 3、 字節三:子包長度,固定填寫0x03,表示後面三個字節的長度;
64 //# 4、 字節四到字節六:包內容:
65 //# a) 字節四:長消息參考號,每個SP給每個用戶發送的每條參考號都應該不同,可以從0開始,每次加1,最大255,便於同一個終端對同一個SP的消息的不同的長短信進行識別;
66 //# b) 字節五:本條長消息的的總消息數,從1到255,一般取值應該大於2;
67 //# c) 字節六:本條消息在長消息中的位置或序號,從1到255,第一條為1,第二條為2,最後一條等於第四字節的值。
68 //# 例子:
69 //# 05 00 03 00 02 01
70 //# 05 00 03 00 02 02
71 int smsPayloadLen = pduPayload[startPos];
72 startPos = startPos + 1;
73 String smsContent = "";
74
75 if (TP_UDHI == 1) {
76 //#長短信--未驗證 可能需要轉無符號
77 byte smsTotal = pduPayload[startPos + 4];
78 byte smsIdx = pduPayload[startPos + 5];
79 startPos = startPos + 6;
80 smsContent = "長短信(" + byteToHex(smsIdx) + "/" + byteToHex(smsTotal) + "}";
81 smsContent = new String(smsContent.getBytes("gbk"));
82 smsPayloadLen = smsPayloadLen - 6;
83 }
84 byte[] smsPayload = new byte[pduPayload.length - startPos];
85 System.arraycopy(pduPayload, startPos, smsPayload, 0, pduPayload.length - startPos);
86
87 if (mTP_DCS == 0) {
88 //#7位編碼--已驗證
89 smsPayloadLen = (smsPayloadLen * 7 + 7) / 8;
90 int asciiData = 0;
91 int lastByteRemain = 0;
92 for (int i = 0; i < smsPayloadLen; i++) {
93 asciiData = asciiData + ((smsPayload[i] & 0x0FF) << lastByteRemain);
94 smsContent = smsContent + (char) ((asciiData & 0x0FF) & 0x7f);
95 asciiData = asciiData >> 7;
96 lastByteRemain = lastByteRemain + 1;
97
98 if (lastByteRemain >= 7) {
99 smsContent = smsContent + (char) ((asciiData & 0x0FF) & 0x7f);
100 asciiData = asciiData >> 7;
101 lastByteRemain = lastByteRemain - 7;
102 }
103 }
104 } else if (mTP_DCS == 8) {
105 //# UCS-2 --已驗證 可正常解析
106 for (int i = 0; i < smsPayloadLen; i = i + 2) {
107 int cc1 = (smsPayload[i] & 0x0FF) * 256;
108 int cc2 = smsPayload[i + 1] & 0x0FF;
109 smsContent = smsContent + (char) (cc1 + cc2);
110
111 }
112 }
113 return smsNumber + ":" + smsContent;
114 }
View Code