日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

SMS短信PDU编码

發(fā)布時間:2024/6/21 综合教程 49 生活家
生活随笔 收集整理的這篇文章主要介紹了 SMS短信PDU编码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目前,發(fā)送短消息常用Text和PDU(Protocol Data Unit,協(xié)議數(shù)據(jù)單元)模式。使用Text模式收發(fā)短信代碼簡單,實現(xiàn)起來十分容易,但最大的缺點是不能收發(fā)中文短信;而PDU模式不僅支持中文短信,也能發(fā)送英文短信。PDU模式收發(fā)短信可以使用3種編碼:7-bit、8-bit和UCS2編碼。7-bit編碼用于發(fā)送普通的ASCII字符,8-bit編碼通常用于發(fā)送數(shù)據(jù)消息,UCS2編碼用于發(fā)送Unicode字符。一般的PDU編碼由A B C D E F G H I J K L M十三項組成。

A:短信息中心地址長度,2位十六進制數(shù)(1字節(jié))。
B:短信息中心號碼類型,2位十六進制數(shù)。
C:短信息中心號碼,B+C的長度將由A中的數(shù)據(jù)決定。
D:文件頭字節(jié),2位十六進制數(shù)。
E:信息類型,2位十六進制數(shù)。
F:被叫號碼長度,2位十六進制數(shù)。
G:被叫號碼類型,2位十六進制數(shù),取值同B。
H:被叫號碼,長度由F中的數(shù)據(jù)決定。
I:協(xié)議標識,2位十六進制數(shù)。
J:數(shù)據(jù)編碼方案,2位十六進制數(shù)。
K:有效期,2位十六進制數(shù)。
L:用戶數(shù)據(jù)長度,2位十六進制數(shù)。
M:用戶數(shù)據(jù),其長度由L中的數(shù)據(jù)決定。J中設(shè)定采用UCS2編碼,這里是中英文的Unicode字符。

PDU編碼協(xié)議簡單說明

例1 發(fā)送:SMSC號碼是+8613800250500,對方號碼是13693092030,消息內(nèi)容是“Hello!”。從手機發(fā)出的PDU串可以是
08 91 68 31 08 20 05 05 F0 11 00 0D 91 68 31 96 03 29 30 F0 00 00 00 06 C8 32 9B FD 0E 01
對照規(guī)范,具體分析:
分段 含義 說明

08 SMSC地址信息的長度 共8個八位字節(jié)(包括91)
91 SMSC地址格式(TON/NPI) 用國際格式號碼(在前面加‘+’)
68 31 08 20 05 05 F0 SMSC地址 8613800250500,補‘F’湊成偶數(shù)個
11 基本參數(shù)(TP-MTI/VFP) 發(fā)送,TP-VP用相對格式
00 消息基準值(TP-MR) 0
0D 目標地址數(shù)字個數(shù) 共13個十進制數(shù)(不包括91和‘F’)
91 目標地址格式(TON/NPI) 用國際格式號碼(在前面加‘+’)
68 31 96 03 29 30 F0 目標地址(TP-DA) 8613693092030,補‘F’湊成偶數(shù)個
00 協(xié)議標識(TP-PID) 是普通GSM類型,點到點方式
00 用戶信息編碼方式(TP-DCS) 7-bit編碼
00 有效期(TP-VP) 5分鐘
06 用戶信息長度(TP-UDL) 實際長度6個字節(jié)
C8 32 9B FD 0E 01 用戶信息(TP-UD) “Hello!”

例2 接收:SMSC號碼是+8613800250500,對方號碼是13693092030,消息內(nèi)容是“你好!”。手機接收到的PDU串可以是
08 91 68 31 08 20 05 05 F0 84 0D 91 68 31 96 03 29 30 F0 00 08 30 30 21 80 63 54 80 06 4F 60 59 7D 00 21
對照規(guī)范,具體分析:
分段 含義 說明

08 地址信息的長度 個八位字節(jié)(包括91)
91 SMSC地址格式(TON/NPI) 用國際格式號碼(在前面加‘+’)
68 31 08 20 05 05 F0 SMSC地址 8613800250500,補‘F’湊成偶數(shù)個
84 基本參數(shù)(TP-MTI/MMS/RP) 接收,無更多消息,有回復地址
0D 回復地址數(shù)字個數(shù) 共13個十進制數(shù)(不包括91和‘F’)
91 回復地址格式(TON/NPI) 用國際格式號碼(在前面加‘+’)
68 31 96 03 29 30 F0 回復地址(TP-RA) 8613693092030,補‘F’湊成偶數(shù)個
00 協(xié)議標識(TP-PID) 是普通GSM類型,點到點方式
08 用戶信息編碼方式(TP-DCS) UCS2編碼
30 30 21 80 63 54 80 時間戳(TP-SCTS) 2003-3-12 08:36:45 +8時區(qū)
06 用戶信息長度(TP-UDL) 實際長度6個字節(jié)
4F 60 59 7D 00 21 用戶信息(TP-UD) “你好!”

若基本參數(shù)的最高位(TP-RP)為0,則沒有回復地址的三個段。從Internet上發(fā)出的短消息常常是這種情形。
注意號碼和時間的表示方法,不是按正常順序順著來的,而且要以‘F’將奇數(shù)補成偶數(shù)。

在PDU Mode中,可以采用三種編碼方式來對發(fā)送的內(nèi)容進行編碼,它們是7-bit、8-bit和UCS2編碼。7-bit編碼用于發(fā)送普通的ASCII字符,它將一串7-bit的字符(最高位為0)編碼成8-bit的數(shù)據(jù),每8個字符可“壓縮”成7個;8-bit編碼通常用于發(fā)送數(shù)據(jù)消息,比如圖片和鈴聲等;而UCS2編碼用于發(fā)送Unicode字符。PDU串的用戶信息(TP-UD)段最大容量是140字節(jié),所以在這三種編碼方式下,可以發(fā)送的短消息的最大字符數(shù)分別是160、140和70。這里,將一個英文字母、一個漢字和一個數(shù)據(jù)字節(jié)都視為一個字符。

需要注意的是,PDU串的用戶信息長度(TP-UDL),在各種編碼方式下意義有所不同。7-bit編碼時,指原始短消息的字符個數(shù),而不是編碼后的字節(jié)數(shù)。8-bit編碼時,就是字節(jié)數(shù)。UCS2編碼時,也是字節(jié)數(shù),等于原始短消息的字符數(shù)的兩倍。如果用戶信息(TP-UD)中存在一個頭(基本參數(shù)的TP-UDHI為1),在所有編碼方式下,用戶信息長度(TP-UDL)都等于頭長度與編碼后字節(jié)數(shù)之和。如果采用GSM 03.42所建議的壓縮算法(TP-DCS的高3位為001),則該長度也是壓縮編碼后字節(jié)數(shù)或頭長度與壓縮編碼后字節(jié)數(shù)之和。

參見詳細英文說明:http://www.dreamfabric.com/sms/

將源串每8個字符分為一組(這個例子中不滿8個)進行編碼,在組內(nèi)字符間壓縮,但每組之間是沒有什么聯(lián)系的。

用C實現(xiàn)7-bit編碼和解碼的算法如下:

// 7-bit編碼
// pSrc: 源字符串指針
// pDst: 目標編碼串指針
// nSrcLength: 源字符串長度
// 返回: 目標編碼串長度
int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
     int nSrc;         // 源字符串的計數(shù)值
     int nDst;         // 目標編碼串的計數(shù)值
     int nChar;        // 當前正在處理的組內(nèi)字符字節(jié)的序號,范圍是0-7
     unsigned char nLeft;     // 上一字節(jié)殘余的數(shù)據(jù)
     
     // 計數(shù)值初始化
     nSrc = 0;
     nDst = 0;
     
     // 將源串每8個字節(jié)分為一組,壓縮成7個字節(jié)
     // 循環(huán)該處理過程,直至源串被處理完
     // 如果分組不到8字節(jié),也能正確處理
     while(nSrc<nSrcLength)
     {
         // 取源字符串的計數(shù)值的最低3位
         nChar = nSrc & 7;
     
         // 處理源串的每個字節(jié)
         if(nChar == 0)
         {
             // 組內(nèi)第一個字節(jié),只是保存起來,待處理下一個字節(jié)時使用
             nLeft = *pSrc;
         }
         else
         {
             // 組內(nèi)其它字節(jié),將其右邊部分與殘余數(shù)據(jù)相加,得到一個目標編碼字節(jié)
             *pDst = (*pSrc << (8-nChar)) | nLeft;
     
             // 將該字節(jié)剩下的左邊部分,作為殘余數(shù)據(jù)保存起來
             nLeft = *pSrc >> nChar;
             // 修改目標串的指針和計數(shù)值 pDst++;
             nDst++; 
         } 
         
         // 修改源串的指針和計數(shù)值
         pSrc++; nSrc++;
     }
     
     // 返回目標串長度
     return nDst; 
}
     
// 7-bit解碼
// pSrc: 源編碼串指針
// pDst: 目標字符串指針
// nSrcLength: 源編碼串長度
// 返回: 目標字符串長度
int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
     int nSrc;         // 源字符串的計數(shù)值
     int nDst;         // 目標解碼串的計數(shù)值
     int nByte;        // 當前正在處理的組內(nèi)字節(jié)的序號,范圍是0-6
     unsigned char nLeft;     // 上一字節(jié)殘余的數(shù)據(jù)
     
     // 計數(shù)值初始化
     nSrc = 0;
     nDst = 0;
     
     // 組內(nèi)字節(jié)序號和殘余數(shù)據(jù)初始化
     nByte = 0;
     nLeft = 0;
     
     // 將源數(shù)據(jù)每7個字節(jié)分為一組,解壓縮成8個字節(jié)
     // 循環(huán)該處理過程,直至源數(shù)據(jù)被處理完
     // 如果分組不到7字節(jié),也能正確處理
     while(nSrc<nSrcLength)
     {
         // 將源字節(jié)右邊部分與殘余數(shù)據(jù)相加,去掉最高位,得到一個目標解碼字節(jié)
         *pDst = ((*pSrc << nByte) | nLeft) & 0x7f;
         // 將該字節(jié)剩下的左邊部分,作為殘余數(shù)據(jù)保存起來
         nLeft = *pSrc >> (7-nByte);
     
         // 修改目標串的指針和計數(shù)值
         pDst++;
         nDst++;
     
         // 修改字節(jié)計數(shù)值
         nByte++;
     
         // 到了一組的最后一個字節(jié)
         if(nByte == 7)
         {
             // 額外得到一個目標解碼字節(jié)
             *pDst = nLeft;
     
             // 修改目標串的指針和計數(shù)值
             pDst++;
             nDst++;
     
             // 組內(nèi)字節(jié)序號和殘余數(shù)據(jù)初始化
             nByte = 0;
             nLeft = 0;
         }
     
         // 修改源串的指針和計數(shù)值
         pSrc++;
         nSrc++;
     }
     
     *pDst = 0;
     
     // 返回目標串長度
     return nDst;
}

需要指出的是,7-bit的字符集與ANSI標準字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、阿拉伯數(shù)字和常用符號的位置兩者是一樣的。用上面介紹的算法收發(fā)純英文短消息,一般情況應(yīng)該是夠用了。如果是法語、德語、西班牙語等,含有 “?”、 “é”這一類字符,則要按上面編碼的輸出去查表,請參閱GSM 03.38的規(guī)定。

8-bit編碼其實沒有規(guī)定什么具體的算法,不需要介紹。

UCS2編碼是將每個字符(1-2個字節(jié))按照ISO/IEC106的規(guī)定,轉(zhuǎn)變?yōu)?6位的Unicode寬字符。在Windows系統(tǒng)中,特別是在2000/XP中,可以簡單地調(diào)用API 函數(shù)實現(xiàn)編碼和解碼。如果沒有系統(tǒng)的支持,比如用單片機控制手機模塊收發(fā)短消息,只好用查表法解決了。

Windows環(huán)境下,用C實現(xiàn)UCS2編碼和解碼的算法如下:

// UCS2編碼
// pSrc: 源字符串指針
// pDst: 目標編碼串指針
// nSrcLength: 源字符串長度
// 返回: 目標編碼串長度
int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
     int nDstLength;         // UNICODE寬字符數(shù)目
     WCHAR wchar[128];       // UNICODE串緩沖區(qū)
     
     // 字符串-->UNICODE串
     nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
     
     // 高低字節(jié)對調(diào),輸出
     for(int i=0; i<nDstLength; i++)
     {
         // 先輸出高位字節(jié)
         *pDst++ = wchar[i] >> 8;
         // 后輸出低位字節(jié)
         *pDst++ = wchar[i] & 0xff;
     }
     
     // 返回目標編碼串長度
     return nDstLength * 2;
}
     
// UCS2解碼
// pSrc: 源編碼串指針
// pDst: 目標字符串指針
// nSrcLength: 源編碼串長度
// 返回: 目標字符串長度
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
     int nDstLength;         // UNICODE寬字符數(shù)目
     WCHAR wchar[128];       // UNICODE串緩沖區(qū)
     
     // 高低字節(jié)對調(diào),拼成UNICODE
     for(int i=0; i<nSrcLength/2; i++)
     {
         // 先高位字節(jié)
         wchar[i] = *pSrc++ << 8;
     
         // 后低位字節(jié)
         wchar[i] |= *pSrc++;
     }
     
     // UNICODE串-->字符串
     nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
     
     // 輸出字符串加個結(jié)束符     
     pDst[nDstLength] = '';     
     
     // 返回目標字符串長度
     return nDstLength;
}

用以上編碼和解碼模塊,還不能將短消息字符串編碼為PDU串需要的格式,也不能直接將PDU串中的用戶信息解碼為短消息字符串,因為還差一個在可打印字符串和字節(jié)數(shù)據(jù)之間相互轉(zhuǎn)換的環(huán)節(jié)。可以循環(huán)調(diào)用sscanf和sprintf函數(shù)實現(xiàn)這種變換。下面提供不用這些函數(shù)的算法,它們也適用于單片機、DSP編程環(huán)境。

// 可打印字符串轉(zhuǎn)換為字節(jié)數(shù)據(jù)
// 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
// pSrc: 源字符串指針
// pDst: 目標數(shù)據(jù)指針
// nSrcLength: 源字符串長度
// 返回: 目標數(shù)據(jù)長度
int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
     for(int i=0; i<nSrcLength; i+=2)
     {
         // 輸出高4位
         if(*pSrc>='0' && *pSrc<='9')
         {
             *pDst = (*pSrc - '0') << 4;
         }
         else
         {
             *pDst = (*pSrc - 'A' + 10) << 4;
         }
     
         pSrc++;
     
         // 輸出低4位
         if(*pSrc>='0' && *pSrc<='9')
         {
             *pDst |= *pSrc - '0';
         }
         else
         {
             *pDst |= *pSrc - 'A' + 10;
         }
         pSrc++;
         pDst++;
     }
     
     // 返回目標數(shù)據(jù)長度
     returnnSrcLength / 2;
}
     
// 字節(jié)數(shù)據(jù)轉(zhuǎn)換為可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01" 
// pSrc: 源數(shù)據(jù)指針
// pDst: 目標字符串指針
// nSrcLength: 源數(shù)據(jù)長度
// 返回: 目標字符串長度
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
     const char tab[]="0123456789ABCDEF";     // 0x0-0xf的字符查找表
     
     for(int i=0; i<nSrcLength; i++)
     {
         // 輸出低4位
         *pDst++ = tab[*pSrc >> 4];
     
         // 輸出高4位
         *pDst++ = tab[*pSrc & 0x0f];
     
         pSrc++;
     }
     
     // 輸出字符串加個結(jié)束符
     *pDst = '';
     
     // 返回目標字符串長度
     return nSrcLength * 2;
}

相關(guān)鏈接:手機短信編碼解碼 在線PDU格式編碼/解碼

總結(jié)

以上是生活随笔為你收集整理的SMS短信PDU编码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 韩国理论午夜 | 亚洲精品小视频 | 中文字幕在线视频免费播放 | 99视频免费在线观看 | 欧美色图一区二区三区 | v片在线观看 | 国产黄色片视频 | 欧美日韩另类视频 | 中文久久久久 | 三上悠亚人妻中文字幕在线 | 91亚洲国产成人精品一区 | 免费看的黄色小视频 | 国产一级久久久久毛片精品 | 免费看黄色漫画 | 精品一区二区在线看 | 国产资源站 | 亚洲成a人片77777精品 | 午夜视频国产 | 日本亚洲欧洲色 | 国产精品成人免费一区二区视频 | 91香蕉视频在线 | 日日草视频 | 欧美日韩国产麻豆 | 色戒电影未测减除版 | 三级黄色免费 | 黑人vs亚洲人在线播放 | av久草| 伊人中文字幕 | 亚洲人成在线免费观看 | 自拍第一页| 秋霞7777鲁丝伊人久久影院 | 人妻无码一区二区三区四区 | 久久婷婷一区 | 五月婷在线观看 | 日b视频在线观看 | 精品国产一区二区三区性色 | 麻豆传媒一区 | 一级全黄裸体免费观看视频 | 国产一区视频在线播放 | 91资源在线观看 | 猛1被调教成公厕尿便失禁网站 | 成年网站免费在线观看 | 狼人综合伊人 | 亚洲一级影院 | 日韩有码av | 色999在线观看 | 婷婷一区二区三区四区 | 精品国产伦一区二区三区 | 亚洲区色| 成熟了的熟妇毛茸茸 | 国产一区二区三区乱码 | 亚洲日本中文 | 琪琪午夜伦理影院7777 | 六月色播| 亚洲夜夜爽 | 欧美精品video| 国产三级在线播放 | 成年人午夜影院 | 中文字幕有码无码人妻av蜜桃 | 超碰在线免费97 | 亚洲激情综合网 | 一级黄色片在线观看 | www.啪啪.com | 四虎视频国产精品免费入口 | 日韩精品无码一区二区三区 | 国产精品色视频 | 色综合激情 | 国产精品天堂 | xxxxx色| 欧美人体一区二区 | 高清不卡一区 | 成人免费视频国产免费 | 2018天天操| 久久精品99久久久久久久久 | 女人喂男人奶水做爰视频 | 97伊人网| 欧美精品一区二区蜜桃 | 韩日精品中文字幕 | 久久久艹| 成人动漫av在线 | 五月婷婷基地 | 黄色精品视频在线观看 | 香蕉视频一区二区三区 | av国产网站 | 高潮一区二区 | 久久黄色一级视频 | 日本打白嫩屁股视频 | 色阁av | 精品69| 最新中文字幕免费 | 极品少妇在线观看 | 波多野结衣一区二区在线 | 精品少妇人妻av一区二区三区 | 久久久久久久久久免费 | 日本欧美韩国国产精品 | 欧美黄色一级片视频 | 毛片毛片毛片毛片毛片毛片毛片毛片 | 又黄又色又爽的视频 | 噜噜噜噜私人影院 |