Java pdu短信解碼全面解析
長短信未驗(yàn)證 有興趣的可以試試
根據(jù)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; //#短信內(nèi)容是否包含協(xié)議頭信息,0 不包含, 1 包含(長短信,push短信) int TP_VPF = (TP_Header >> 3) & 3; //#是否包含有效期字節(jié),0 不包含, 其他 包含 // #00表示無有效期,TP-VP設(shè)置為00。 // #10表示相對格式,TP-VP占用1字節(jié)。 // #01表示增加格式,TP-VP占用7字節(jié)。 // #11表示絕對格式,TP-VP占用7字節(jié) int TP_MMS = (TP_Header >> 2) & 1;//# TP-MMS(TP-More-Message-to-Send):1 短信中心沒有更多的消息發(fā)送 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位編碼,設(shè)置為“02”使用8位編碼,設(shè)置為“08”使用UCS2編碼。 startPos = startPos + 2; if (TP_VPF == 2) { startPos = startPos + 1; } else if (TP_VPF == 1 || TP_VPF == 3) { startPos = startPos + 7; } //# 長短信:內(nèi)容前面需要增加6個字段 //# 1、 字節(jié)一:包頭長度,固定填寫0x05; //# 2、 字節(jié)二:包頭類型標(biāo)識,固定填寫0x00,表示長短信; //# 3、 字節(jié)三:子包長度,固定填寫0x03,表示后面三個字節(jié)的長度; //# 4、 字節(jié)四到字節(jié)六:包內(nèi)容: //# a) 字節(jié)四:長消息參考號,每個SP給每個用戶發(fā)送的每條參考號都應(yīng)該不同,可以從0開始,每次加1,最大255,便于同一個終端對同一個SP的消息的不同的長短信進(jìn)行識別; //# b) 字節(jié)五:本條長消息的的總消息數(shù),從1到255,一般取值應(yīng)該大于2; //# c) 字節(jié)六:本條消息在長消息中的位置或序號,從1到255,第一條為1,第二條為2,最后一條等于第四字節(jié)的值。 //# 例子: //# 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) { //#長短信--未驗(yàn)證 可能需要轉(zhuǎn)無符號 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位編碼--已驗(yàn)證 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 --已驗(yàn)證 可正常解析 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短信解碼全面解析,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
關(guān)于Java繼承中父類和子類構(gòu)造函數(shù)的問題
這篇文章主要介紹了關(guān)于Java繼承中父類和子類構(gòu)造函數(shù)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10springboot?maven?打包插件介紹及注意事項(xiàng)說明
這篇文章主要介紹了springboot?maven?打包插件介紹及注意事項(xiàng)說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12Java基礎(chǔ)知識精通循環(huán)結(jié)構(gòu)與break及continue
循環(huán)結(jié)構(gòu)是指在程序中需要反復(fù)執(zhí)行某個功能而設(shè)置的一種程序結(jié)構(gòu)。它由循環(huán)體中的條件,判斷繼續(xù)執(zhí)行某個功能還是退出循環(huán),選擇結(jié)構(gòu)用于判斷給定的條件,根據(jù)判斷的結(jié)果判斷某些條件,根據(jù)判斷的結(jié)果來控制程序的流程2022-04-04JAVA中方法的聲明及使用方式(繼承、多態(tài)、封裝)
這篇文章主要介紹了JAVA中方法的聲明及使用方式(繼承、多態(tài)、封裝),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02java數(shù)據(jù)庫操作類演示實(shí)例分享(java連接數(shù)據(jù)庫)
java數(shù)據(jù)庫操作類演示實(shí)例分享,大家參考使用吧2013-12-12SpringBoot項(xiàng)目微信云托管入門部署實(shí)踐
本文主要介紹了SpringBoot項(xiàng)目微信云托管入門部署實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03