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 }
测试数据
1 byte[] smsDataCN = { 2 0x00, 0x01, 0x00, 3 0x08, (byte) 0x91, 0x68, 0x31, 0x08, 0x10, 0x00, 0x05, 4 (byte) 0xf0, 0x23, 0x01, (byte) 0xb9, 0x0b, (byte) 0x81, 0x31, 5 (byte) 0x99, (byte) 0x98, 0x30, 0x67, (byte) 0xf7, 0x00, 6 0x08, 0x16, 0x55, 0x4a, 0x55, 0x4a, 0x55, 0x4a, 0x55, 0x4a, 0x55, 7 0x4a, 0x55, 0x4a, 0x54, 0x75, 0x54, 0x75, 0x54, 0x75, 0x60, 0x69, 8 0x68, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 0x00, 0x00, 0x00, 0x00, 0x00};
1 byte[] smsDataEN = { 2 0x00,0x03,0x00,0x08, 3 (byte)0x91, 4 0x68,0x31,0x08,0x10,0x00, 5 0x05, 6 (byte)0xf0, 7 0x17,0x01, 8 (byte)0xbb, 9 0x0b, 10 (byte)0x81, 11 0x31, 12 (byte)0x99, 13 (byte)0x98, 14 0x30, 15 0x68, 16 (byte)0xf7, 17 0x00,0x00,0x0b, 18 (byte)0xe8, 19 0x32, 20 (byte)0x9b, 21 (byte)0xfd, 22 0x06, 23 (byte)0xdd, 24 (byte)0xdf, 25 0x72, 26 (byte)0xb2, 27 0x0b, 28 0x08, 29 0x16, 0x55, 0x4a, 0x55, 0x4a, 0x55, 30 0x4a, 0x55, 0x4a, 0x55, 31 0x4a, 0x55, 0x4a, 0x54, 0x75, 0x54, 0x75, 0x54, 0x75, 0x60, 0x69, 32 0x68, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 0x00, 0x00, 0x00, 0x00, 0x00};