手机短信息SMS开发—编码,解码

合集下载

短信格式(sms)以及编码总结

短信格式(sms)以及编码总结

短信格式(sms)以及编码总结第一篇:短信格式(sms)以及编码总结短信格式(sms)以及编码总结一、短信猫操作分为三种模式: Block、Pdu 和 Text1、Block 模式基本已经被 Pdu 模式取代,没有具体研究。

2、Text 模式比较简单,但是支持的设备不是很全,而且不能实现中文。

AT + CGMF=1 AT +CGMS= “ *** ” ,129 >Hello World!3、Pdu 模式Pdu 编码主要包括两个主要的部分,一是 pdu 串的整体数据格式,分别因为发送信息串和接收信息串而有区别,二是pdu 中文本部分的编码,分别因为字符集而不同。

我们也可以这样来理解这个 pdu 编码的格式,sms 相当于一个协议栈,最简单的协议栈:根据 gsm03.40 规范,sms 协议包括以下几层:1、SM-AL :应用层。

这个部分就是数据部分。

2、SM-TL :传输层。

我们可以清楚的看到这里描述了主要的短信内容,包括发送号码,接收号码,信息类型,编码,数据报长度等等,这也是我们编程主要要面对的问题。

3、SM-RL :中继层。

这个指的是短信在网关之间中继需要的协议。

4、SM-LL:链路层。

从上述描述中我们可以清楚的看到,我们编程主要集中于传输层。

二、短信传送有三种编码: 7 位,8 位,UniCode1、英文 7 位编码这是 gsm 的默认编码方式由于这样的移位,我们可以看到我们能发的最多英文字符等于:140*8/7 = 160。

2、数据 8 位编码8-bit 编码通常用于发送数据消息,比如图片和铃声等;3、中文pdu 编码发送中文时,必须用UCS2(utf-16)进行编码,最多可以发 140/2 = 70 个汉字。

UniCode 编码转换也比较简单,以中文为例,一个中文字符是两个字节,直接对高位字节和低位字节进行十六进制转换就可以了。

如“欢迎”,UniCode 编码是6B22 8FCE,这同时也就是转换的结果,如果发送的串中有英文字符,那么在前面补全 00,以保证一个字符对应两个字节。

短信解码及编码

短信解码及编码

using System;using System.Text;namespace CN.SMSLib{/// <summary>/// By popcorn 2004.5。

/// cnpopcorn@/// </summary>public class CNText{public CNText(){}/// <summary>/// 编码格式/// </summary>public enum GSMCode{Bit7=0,Bit8=1,UCS2=2}/// <summary>/// 对整个短信息进行解码/// </summary>/// <param name="s">要解码的信息</param>/// <param name="phone">解码后的电话号码</param>/// <param name="text">解码后的短信内容</param>/// <param name="sendTime">短信时间戳</param>/// <param name="code">使用的编码方式</param>/// <returns>成功返回true</returns>static public bool DecodingMsg(string s,ref string phone,ref string text,ref DateTime sendTime,ref GSMCode code,ref string SCA){try{//短信息中心intiLength=int.Parse(s.Substring(0,2),System.Globalization.NumberStyles.AllowHexSpe cifier);if(iLength>0){if(s.Substring(2,2)=="91"){SCA+="+";iLength--;}for(int i=0;i<iLength*2;i+=2){SCA+=s.Substring(5+i,1);SCA+=s.Substring(4+i,1);}if(SCA.EndsWith("F"))SCA=SCA.Remove(SCA.Length-1,1);}s=s.Remove(0,iLength*2+6);//发送方号码iLength=int.Parse(s.Substring(0,2),System.Globalization.NumberStyles.AllowHexSpe cifier);if(s.Substring(2,2)=="91"){phone="+";}if(iLength%2==1)iLength++;for(int i=0;i<iLength;i+=2){phone+=s.Substring(5+i,1);phone+=s.Substring(4+i,1);}if(phone.EndsWith("F"))phone=phone.Remove(phone.Length-1,1);s=s.Remove(0,iLength+6);//编码方式if(s.Substring(0,2)=="08")code=GSMCode.UCS2;else if(s.Substring(0,2)=="00")code=GSMCode.Bit7;elsecode=GSMCode.Bit8;s=s.Remove(0,2);//时间戳sendTime=new DateTime(int.Parse("20"+s.Substring(1,1)+s.Substring(0,1)),int.Parse(s.Substring(3,1)+s.Substring(2,1)),int.Parse(s.Substring(5,1)+s.Substring(4,1)),int.Parse(s.Substring(7,1)+s.Substring(6,1)),int.Parse(s.Substring(9,1)+s.Substring(8,1)),int.Parse(s.Substring(11,1)+s.Substring(10,1))); s=s.Remove(0,16);//收到的信息if(code==GSMCode.Bit7){text=DecodingBit7(s);}else if(code==GSMCode.UCS2){text=DecodingUCS2(s);}else{text=DecodingBit8(s);}return true;}catch{return false;}}/// <summary>/// 对短信息中心进行编码/// </summary>/// <param name="s">要编码的号码</param>/// <returns>编码后的号码</returns>static public string EncodingSCA(string s){StringBuilder sb=new StringBuilder();if(s.Length==0){sb.Append("00");return sb.ToString();}if(s.StartsWith("+")){sb.Append("91"); //用国际格式号码(在前面加‘+’) s=s.Remove(0,1);}else{sb.Append("C8");}if(s.Length%2==1)s+="F";for(int i=0;i<s.Length;i+=2){sb.Append(s.Substring(i+1,1));sb.Append(s.Substring(i,1));}string len=(sb.Length/2).ToString("X2");return len+sb.ToString();}/// <summary>/// 对电话号码进行编码/// </summary>/// <param name="mobileNo">要编码的电话号码</param> /// <returns>编码后的电话号码</returns>static public string EncodingNumber(string mobileNo) {StringBuilder sb=new StringBuilder();if(mobileNo.StartsWith("+")){sb.Append("91");mobileNo=mobileNo.Remove(0,1);}else{sb.Append("C8");}string len=mobileNo.Length.ToString("X2");if(mobileNo.Length%2==1)mobileNo+="F";for(int i=0;i<mobileNo.Length;i+=2){sb.Append(mobileNo.Substring(i+1,1));sb.Append(mobileNo.Substring(i,1));}return len+sb.ToString();}/// <summary>/// 使用7-bit进行编码/// </summary>/// <param name="s">要编码的英文字符串</param>/// <returns>信息长度及编码后的字符串</returns>static public string EncodingBit7(string s){int iLeft=0;string sReturn="";StringBuilder sb=new StringBuilder();for(int i=0;i<s.Length;i++){// 取源字符串的计数值的最低3位int iChar = i & 7;byte bSrc=(byte)char.Parse(s.Substring(i,1));// 处理源串的每个字节if(iChar == 0){// 组内第一个字节,只是保存起来,待处理下一个字节时使用iLeft = (int)char.Parse(s.Substring(i,1));}else{// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节 sReturn=(bSrc << (8-iChar) | iLeft).ToString("X4");// 将该字节剩下的左边部分,作为残余数据保存起来iLeft = bSrc >> iChar;// 修改目标串的指针和计数值 pDst++;sb.Append(sReturn.Substring(2,2));}}sb.Append(sReturn.Substring(0,2));return (sb.Length/2).ToString("X2")+sb.ToString();}/// <summary>/// 对7-bit编码进行解码/// </summary>/// <param name="s">要解码的字符串</param>/// <returns>解码后的英文字符串</returns>static public string DecodingBit7(string s){int iByte=0;int iLeft=0;// 将源数据每7个字节分为一组,解压缩成8个字节// 循环该处理过程,直至源数据被处理完// 如果分组不到7字节,也能正确处理System.Text.StringBuilder sb=new System.Text.StringBuilder();for(int i=0;i<s.Length;i+=2){bytebSrc=byte.Parse(s.Substring(i,2),System.Globalization.NumberStyles.AllowHexSpeci fier);// 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节sb.Append((((bSrc << iByte) | iLeft) & 0x7f).ToString("X2"));// 将该字节剩下的左边部分,作为残余数据保存起来iLeft = bSrc >> (7-iByte);// 修改字节计数值iByte++;// 到了一组的最后一个字节if(iByte == 7){// 额外得到一个目标解码字节sb.Append(iLeft.ToString("X2"));// 组内字节序号和残余数据初始化iByte = 0;iLeft = 0;}}string sReturn=sb.ToString();byte [] buf=new byte[sReturn.Length/2];for(int i=0;i<sReturn.Length;i+=2){buf[i/2]=byte.Parse(sReturn.Substring(i,2),System.Globalization.NumberStyles.All owHexSpecifier);}return System.Text.Encoding.ASCII.GetString(buf);}/// <summary>/// 使用8-bit进行编码/// </summary>/// <param name="s">要编码的字符串</param>/// <returns>信息长度及编码后的字符串</returns>static public string EncodingBit8(string s){StringBuilder sb=new StringBuilder();byte [] buf=Encoding.ASCII.GetBytes(s);sb.Append(buf.Length.ToString("X2"));for(int i=0;i<buf.Length;i++){sb.Append(buf[i].ToString("X2"));}return sb.ToString();}/// <summary>/// 使用8-bit进行解码/// </summary>/// <param name="s">要解码的字符串</param>/// <returns>解码后的字符串</returns>static public string DecodingBit8(string s){byte [] buf=new byte[s.Length/2];StringBuilder sb=new StringBuilder();for(int i=0;i<s.Length;i+=2){buf[i/2]=byte.Parse(s.Substring(i,2),System.Globalization.NumberStyles.AllowHexS pecifier);}return Encoding.ASCII.GetString(buf);}/// <summary>/// 中文短信息UCS2编码/// </summary>/// <param name="s">要编码的中文字符串</param>/// <returns>信息长度及编码后的字符串</returns>static public string EncodingUCS2(string s){StringBuilder sb=new StringBuilder();byte [] buf=Encoding.Unicode.GetBytes(s);sb.Append(buf.Length.ToString("X2"));for(int i=0;i<buf.Length;i+=2){sb.Append(buf[i+1].ToString("X2"));sb.Append(buf[i].ToString("X2"));}return sb.ToString();}/// <summary>/// 中文短信息UCS2解码/// </summary>/// <param name="s">要解码的信息</param>/// <returns>解码后的中文字符串</returns>static public string DecodingUCS2(string s){byte [] buf=new byte[s.Length];for(int i=0;i<s.Length;i+=4){buf[i/2]=byte.Parse(s.Substring(2+i,2),System.Globalization.NumberStyles.AllowHe xSpecifier);buf[i/2+1]=byte.Parse(s.Substring(i,2),System.Globalization.NumberStyles.AllowHe xSpecifier);}return Encoding.Unicode.GetString(buf);}}}。

短信中文编码的问题

短信中文编码的问题

字符集之:短信中文编码的问题收藏SMS是由Esti 所制定的一个规范(GSM 03.40 和GSM 03.38)。

有两种方式来发送和接收SMS消息:文本模式或者PDU(protocol description unit)模式。

文本模式只能发送普通的ASCII字符,而要发送图片、铃声、其它编码的字符(如中文)就必须采用PDU模式。

PDU模式中,可以采用三种编码方式来编码要发送的内容,分别是7-bit编码、8-bit编码、16-bit编码。

7-bit编码用于发送普通的ASCII字符;8-bit编码通常用于发送数据消息,比如图片和铃声等;而16-bit编码用于发送Unicode字符。

在这三种编码方式下,可以发送的最大字符数分别是160、140、70。

若要发送中文(或日文等),必须采用PDU模式的Unicode编码方式。

我最近参与了一个在linux下收发短信的项目。

其中,需要实现中文的发送和接收。

由于原来没有中文编码、Unicode编码的经验,所以查了一些资料,也在一些论坛上提了一些问题。

现在把它整理出来,希望对以后再做类似项目的朋友有个帮助。

我写的比较简单,关于PDU 的规范,可以看这里:/sustain/SMS_PDU-mode.p df ,或者去wavecom的网站上找找看。

1、GB2312 编码到Unicode 编码的转换在Redhat 7.3系统上,默认是用GB2312编码保存中文字符的(对于中英文混合的文本也是如此)。

所以首先需要把GB2312 编码的字符串转换到Unicode编码的字符串。

G B2312编码是一种多字节编码方式,对于中文,用2个字节表示,对于英文,用1个字节表示,就是英文的ascii码。

(注:我没有仔细看过GB2312编码的规范,以上理解是实际开发中得出来的,不能保证正确性)。

Unicode编码是双字节编码方式,对所有字符,都采用2个字节编码。

在linux平台上,GB2312编码到Unicode编码的转换,可以有三种实现方式(或者更多):1)、用mbstowcs () 函数。

移动短消息中纯英文消息的编码及解码

移动短消息中纯英文消息的编码及解码

协议类 型和正文 , 正文长度可达 10字节 , 4 它们都 以十
六进制表示 。 对于 中文短消息 , 一条 消息 的最大长度为 7 0个汉字 : 对于 中文混杂的短消息 . 中文字符与英文字 符的长 度共 和为 7 0个 : 如果 是纯英文 的短 消息 , 消 则 息 中最 多可有 10个 英文字符 。其原 因是 中英文 在短 6 消息 中是采用 的不用的编码方案 ,如果 是 中文或 中英 文混 杂 . 则所有 字符采用 U i d 编码 , ne e o 而如果 是纯英
储 , 是 需 要进 行 处 理 , 而 即转 换 成 8位 的 编 码 . 此 1 因 0 4
字符的空间可 以存储 10 字符 。 6个
2 短 消息 P U字符 串的 组成 D
短 消 息 在 从 一 个 移 动 终 端 ( 手 机 ) 送 到 另 一 个 如 发 移 动 终 端 时 至 少 有 两 个 过 程 ,即 移 动 台终 止 的 短 消 息 与 移 动 台 发 起 的短 消 息 。移 动 台 发 起 的短 消 息 实 际 上 就是 用 户从 手 机 中发 出 的短 消 息 ,移 动 台 终 止 的短 消 息 就 是 用 户 手 机 接 收 到 的 短 消 息 。 这 两 种 短 消 息 的格
T x M d 是纯 文本方式 , et o e 可使 用不 同的字 符集 . 主要
用 于 欧美 地 区 。 技 术 上 说 也 可 用 于 发 送 中 文 短 消 息 . 从
但 国 内手机 基本 上不 支持 ;D o e 所有 手 机支 PUMd被 持 , 以接下来主要讨论 P U格式的短消息 报文。 所 D

K yw rsSo m saesomesg n i et oeP U;oi itcaatr e od:hr es ; r s ei E g s t d ;D C n i 7d i hrc s t g ht a n l h xm d gn g e

SMS短信的C语言代码(转)

SMS短信的C语言代码(转)

SMS短信的C语言代码(转)SMS短信的C语言代码(转)1.消息编码与解码用C实现7-bit编码和解码的算法如下:// 7-bit编码// pSrc: 源字符串指针// pDst: 目标编码串指针// nSrcLength: 源字符串长度// 返回: 目标编码串长度int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength){int nSrc; // 源字符串的计数值int nDst; // 目标编码串的计数值int nChar; // 当前正在处理的组内字符字节的序号,范围是0-7unsigned char nLeft; // 上一字节残余的数据// 计数值初始化nSrc = 0;nDst = 0;// 将源串每8个字节分为一组,压缩成7个字节// 循环该处理过程,直至源串被处理完// 如果分组不到8字节,也能正确处理while(nSrc{// 取源字符串的计数值的最低3位nChar = nSrc & 7;// 处理源串的每个字节if(nChar == 0){// 组内第一个字节,只是保存起来,待处理下一个字节时使用nLeft = *pSrc;}else{// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节*pDst = (*pSrc << (8-nChar)) | nLeft;// 将该字节剩下的左边部分,作为残余数据保存起来nLeft = *pSrc >> nChar;// 修改目标串的指针和计数值 pDst++;nDst++;}// 修改源串的指针和计数值pSrc++; nSrc++;}// 返回目标串长度return nDst;}// 7-bit解码// pSrc: 源编码串指针// pDst: 目标字符串指针// nSrcLength: 源编码串长度// 返回: 目标字符串长度int gsmDecode7bit(const unsigned char* pSrc, char* pDst, int nSrcLength){int nSrc; // 源字符串的计数值int nDst; // 目标解码串的计数值int nByte; // 当前正在处理的组内字节的序号,范围是0-6unsigned char nLeft; // 上一字节残余的数据// 计数值初始化nSrc = 0;nDst = 0;// 组内字节序号和残余数据初始化nByte = 0;nLeft = 0;// 将源数据每7个字节分为一组,解压缩成8个字节// 循环该处理过程,直至源数据被处理完// 如果分组不到7字节,也能正确处理while(nSrc{// 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节*pDst = ((*pSrc << nByte) | nLeft) & 0x7f;// 将该字节剩下的左边部分,作为残余数据保存起来nLeft = *pSrc >> (7-nByte);// 修改目标串的指针和计数值pDst++;nDst++;// 修改字节计数值nByte++;// 到了一组的最后一个字节if(nByte == 7){// 额外得到一个目标解码字节*pDst = nLeft;// 修改目标串的指针和计数值pDst++;nDst++;// 组内字节序号和残余数据初始化nByte = 0;nLeft = 0;}// 修改源串的指针和计数值pSrc++;nSrc++;}*pDst = 0;// 返回目标串长度return nDst;}需要指出的是,7-bit的字符集与ANSI标准字符集不完全一致,在0x20以下也排布了一些可打印字符,但英文字母、阿拉伯数字和常用符号的位置两者是一样的。

SMS分类及编码方案

SMS分类及编码方案

空闲单元 已用单元 MS接收 已读 MS接收 未读 MS发出
RETURN
RETURN
TP-Validity-Period-Format (TP-VPF)
Bit 3 0 0 1
1
Bit 4 0 1 0 1
TP-VP 不存在 TP-VP 以enhanced 格式存在(7bytes) TP-VP 以relative 格式存在(1byte)
TP-VP 以absolute 格式存在(7bytes)
数据短信为F6,参阅GSM和VPF要求的格式一致
7 TP UDL M
1
User Data Length
8 TP UD
O
User Data,如果TP-UDHI为1,则数据包括一 个数据头,第一个字节表示数据头的长度。
SMS SUBMIT 举例
Submit型短信,允许SC接收有 相同TP-MR的短信,有效期格 式为relative,1个字节,不需要 状态回复,无短信头,设置有 回复路径参数
具体计算方法可以参阅GSM03.40 章节(9.2.3.12)
RETURN
SMS DELIVER状态字
BIT CONTENT VALUE
EXPLANATION
0 TP-MTI
1
0 短信类型指示器
0
2
TP-MMS
0/1 有/没有 更多短信等待下发
3
4
5
TP-SRI
0/1 状态报告 不会/会 返回终端
TP DT
发送成功
参考文献
GSM 11.11 GSM 03.40 GSM 03.38
Message Reference (TP-MR)
TP-MR是MS传到SC的SMS-SUBMIT或 SMS-COMMAND类型短信的数量。每条 SMS-SUBMIT或SMS-COOMAND短信传 输出去MS会把TP-MR的值加1。每条 SMS-SUBMIT的TP-MR的值是从 GSM11.11中规定的LAST-USED-TP-MR 文件(6F43)中得到的。发出SMSSUBMIT后,要更新6F43文件

手机短信编码

手机短信编码

return sb.toString().toUpperCase(); }
实现 UCS2 编码的 Java 代码如下:
public String encode(String src){ StringBuilder sb = new StringBuilder(); char[] cs = src.toCharArray(); int tmp = 0; //存放目标串
个字节。“91 表示地址类型,采用的是国际电话号码格式。剩余的 7 个字节是地址值。 将数据中心的地址从左至右两个一组掉换位置看作一个十六进制数作为一个字节组成地址 值(如果号码个数为奇数,则在右边以‘F 补足凑成偶数后再换位)。 2 TPDU 的格式
2.1 First-Octet
上面给出的是最简单的一种情况,具体设置参考 GSM03.40(9.2.3 小节)。 a) TP-MTI(Message Type Indicator) 发送短信息时需要将位 0 和位 1 设置为 1 和 0。 b) TP-RD(Reject Duplicates) 位 2 设置位 0 表示信息中心能够接收从同一个地址发送的具有相同 TP-DA 和 TP-MR 的短信息。 c) TP-VPF(Validity Period Format) 短信息的有效期,用于指示 TP-VP。 00 表示无有效期,TP-VP 设置为 00。 10 表示相对格式,TP-VP 占用 1 字节。 01 表示增加格式,TP-VP 占用 7 字节。 11 表示绝对格式,TP-VP 占用 7 字节。 其余设置为非法设置。相对格式下的有效时间计算公式为:
sb.append(String.format("%02x", tmp)); iLeft = cs[i]>>iChar; //当前值剩余的部分 }

手机短信的PDU编码和解码

手机短信的PDU编码和解码

手机短信的PDU编码和解码手机短信的PDU编码和解码(2009-10-28 23:10:36)标签:杂谈共有三种方式来发送和接收SMS信息:Block Mode, Text Mode 和PDU Mode。

其中PDU Mode被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式。

发送短消息常用Text和PDU(Protocol Data Unit,协议数据单元)模式。

使用Text模式收发短信代码简单,实现起来十分容易,但最大的缺点是不能收发中文短信;而PDU模式不仅支持中文短信,也能发送英文短信。

PDU模式收发短信可以使用3种编码:7-bit、8-bit 和UCS2编码。

7-bit编码用于发送普通的ASCII字符,它将一串7-bit的字符(最高位为0)编码成8-bit的数据,每8个字符可“压缩”成7个;8-bit编码通常用于发送数据消息,比如图片和铃声等;而UCS2编码用于发送Unicode字符。

在这三种编码方式下,PDU串的用户信息(TP-UD)段最大容量(可以发送的短消息的最大字符数)分别是160、140和70。

这里,将一个英文字母、一个汉字和一个数据字节都视为一个字符。

PDU串的用户信息长度(TP-UDL),在各种编码方式下意义有所不同。

7-bit编码时,指原始短消息的字符个数,而不是编码后的字节数。

8-bit编码时,就是字节数。

UCS2编码时,也是字节数,等于原始短消息的字符数的两倍。

如果用户信息(TP-UD)中存在一个头(基本参数的TP-UDHI为1),在所有编码方式下,用户信息长度(TP-UDL)都等于头长度与编码后字节数之和。

如果采用GSM 03.42所建议的压缩算法(TP-DCS的高3位为001),则该长度也是压缩编码后字节数或头长度与压缩编码后字节数之和。

PDU 相当于一个数据包,它由构成消息(SMS)的信息组成。

作为一种数据单元,它必须包含源/目的地址、保护(有效)时间、数据格式、协议类型和正文,正文长度可达140字节,它们都以十六进制表示。

消息编码对应的术语

消息编码对应的术语

消息编码对应的术语
消息编码( Message(Encoding)是一种用于在通信系统中传输数据的方法。

它涉及到将原始数据转换为可以传输的形式,以便在接收端可以还原为原始数据。

消息编码通常涉及到以下术语:
1.(编码(Encoding):将原始数据转换为另一种形式的过程。

在消息编码中,这通常涉及到将数据转换为可以传输的格式,如二进制代码或文本字符串。

2.(编码器( Encoder):执行编码过程的设备或软件。

它可以将原始数据转换为特定的编码格式。

3.(压缩 Compression):在消息编码中,压缩可以用于减少传输的数据量。

这通常通过删除数据中的重复部分或使用压缩算法来实现。

4.(解码( Decoding):将编码的数据还原为原始数据的过程。

解码器是执行此操作的设备或软件。

5.(解压缩 Decompression):解压缩与压缩相反,用于还原经过压缩的数据。

6.(错误检测( Error(Detection):在消息编码过程中,错误检测用于检测传输过程中可能发生的错误。

这通常涉及到使用校验和或校验位等算法。

消息编码有多种技术,包括位流编码、二进制补码、格雷码、霍夫曼编码等。

每种技术都有其特定的优点和适用场景,如高压缩比、低误码率等。

消息编码在各种通信系统中都有应用,包括但不限于电话、网络、卫星通信、无线通信等。

它对于确保数据的可靠传输和正确还原至关重要。

Android平台MMS_SMS的PDU编码研究

Android平台MMS_SMS的PDU编码研究

软件Chi na lntegr ated Cir c ultAn d r o i d 平台MM S /S M S 的 PDU 编码研究杨小见,任家富,黄美传(成都理工大学信息科学与技术学院,四川 成都,610059)摘要:因为当前 Google 的 Android 操作系统大为盛行,所以像短信、通话这些移动平台的基本通信功能就显得格外关键。

PDU 编码,作为一种较为先进的信息编码方式正为广大技术开发人员所接受,本文研究 了 SMS 发送 PDU 的编码过程,并且结合实例对编码原理进行剖析,验证了 PDU 编码的可行性。

关键字:Android;SMS/MMS;PDUPDU encoding of MMS/SM S base on Android OSYANG Xiao-jian ,REN Jia-fu ,HUANG Mei-chuan(College of Information Science and Technology,CDUT,Chengdu 601159,china )A b s t ract :A s G oog l e ’s A nd r o i d OS is be c o m i n g more and more p o pu l a r , the basic fun c t i o ns of m o b il e p l atf o r m , su c h as SMS and phone turn out to be particularly i mp o r tant . S o , PDU en c o d i n g is widely accepted by deve l o pe r s . T h i s paper shows how to encode and send messa g es , and presents the feasibility of PDU en c o d i n g based on the en c o d i n g the o r y .Key w ord s :A nd r o i d ; SMS /MMS ; PDU1 引言效地解决了通信编码[1]的很多问题,比起传统的编码 方式有着较大的优势。

短信解析原理

短信解析原理

短信解析原理
短信解析(SMS parsing)是将接收到的短信内容进行分析、解码和提取信息的过程。

以下是短信解析的一般原理:
1.短信接收:当手机接收到短信时,短信的内容会被传输到手机的消息收件箱中。

2.短信解码:手机会根据短信的编码方式(如GSM 7位编码或UCS-2编码等)对短信内容进行解码,将其转换为可读的文本。

3.短信分析:解码后的短信内容将被进一步分析。

这通常涉及到对短信的结构和语义进行解析,以提取有用的信息。

4.信息提取:根据需要,短信解析程序会从短信内容中提取出需要的信息。

这可以通过使用文本匹配、正则表达式等技术来实现。

5.数据处理:提取到的信息可以进一步进行处理,如存储到数据库中、发送到其他系统或进行特定的操作。

手机短信PDU编码与解码

手机短信PDU编码与解码
sTo += "F";
//号码两两对换
sTo = Swap2(sTo);
CString sTPDA;
sTPDA.Format("%02X%s%s", nAL, sTA, sTo);
//短信===================
//将消息转换成UNICODE编码
if(sFormat == "00")
nBits = 7;
if(sFormat == "04")
nBits = 8;
sms.m_sBody = HEX2String(cBuffer + nBegin, nLength, nBits);
}
catch(CException * e)
}
//免提
else
{
pdu.m_sPDUBody.Format(_T("001100%s001801%02X%s"),
sTPDA, sSMS.GetLength() / 2, sSMS);
}
pdu.m_sHeader.Format(_T("AT+CMGS=%03d"), pdu.m_sPDUBody.GetLength() / 2 - 1);
{
CString sDecode;
switch(nBits)
{
//B7 to ANSI
case 7:
{
unsigned char nch = 0;
for(int i = 0; i < nLength; i++)
{
unsigned char ch;

SMS短消息PDU编码与解码详细信息

SMS短消息PDU编码与解码详细信息

西门子TC35T用户说明书2SMS短消息PDU编码与解码详细信息GF-1000 GSM MODEM短信收发例子程序SMS/PDU 2007-04-21 20:48:43 阅读466 评论4 字号:大中小订阅1.短信控制终端GF-1000 GSM MODEM,模块采用西门子公司的TC35i,它由GSM基带处理器、电源专用集成电路、射频电路和闪速存储器等部分组成,负责处理GSM蜂窝设备中的音频、数据和信号,内嵌的软件部分执行应用接口和所有GSM协议栈的功能。

TC35支持中文短信息,工作在EGSM900和GSM1800双频段,电源范围为3.3~5.5V,可传输语音和数据信号,消耗功率在EGSM900(4类)和GSM1800(1类)分别为2W和1W,通过接口连接器和天线连接器分别连接SIM卡读卡器和天线。

TC35的数据接口(CMOS电平)通过AT命令可双向传输指令和数据,可选波特率为300bit/s~115kbit/s,自动波特率为1.2k~115kbit/s。

它支持文本和移动运营商提供。

设置短消息中心号码的指令格式为:AT+CSCA=+86138********//注释(短消息中心号码) 是回车符号,是回车换行符号。

设置正确则模块返回OK。

(3)读取短消息服务中心则使用命令:读取短消息服务中心号码的命令格式:AT+CSCA=?//注释是回车符号指令正确TC35i模块应该返回:+CSCA:″8613800531500″。

(4)设置短消息到达自动提示设置短消息到达自动提示的指令格式为:AT+CNMI=1,1,0,0,1设置正确则TC35i模块返回:OK。

设置此命令可使模块在短消息到达后向串口发送指令:+CMTI:″SM″,INDEX(信息存储位置)。

通过TC35i发送短消息的方法为:PC上的控制软件按照PDU的格式发送和接收数据,短消息的内容可以是中文或者其他字符。

在PDU模式,如果发送短消息,则首先发送短消息数据的长度:(5)发送短消息数据的长度命令格式:AT+CMGS=(先得用AT+CMGF?去查看当前的数据发送格式是否为PDU,即CMGF =0,若不为0,这需要重新设置CMGF=0)等待TC35i模块返回ASCII字符">",则可以将PDU数据输入,PDU数据以按键(也就是0x1a)作为结束符。

SMSPDU编码数据串格式分析

SMSPDU编码数据串格式分析

SMSPDU编码数据串格式分析PDU协议数据单元详细介绍PDU 相当于⼀个数据包,它由构成消息(SMS)的信息组成。

作为⼀种数据单元,它必须包含源/⽬的地址、保护(有效)时间、数据格式、协议类型和正⽂,正⽂长度可达140字节,它们都以⼗六进制表⽰。

PDU结构根据短消息由移动终端发起或以移动终端为⽬的⽽不同。

PDU 中 USC 16bit编码⽤于发送Unicode字符,即中⽂等,7bit只能发ASCII字符,8bit⽤来发数据信息如图⽚铃⾳等。

短信息内容长度140字节,最⼤可以发送160个字符,其中每个字符与编码⽅式占⽐为 [160字符/7位],[140字符/8位]或[70个字符/16位],在3GPP TS 24.011, ⼦条款 7.3. 定义了SMS消息应被封装在RPDUs(中继协议数据单元)数据串中。

其中RPDU数据通过SIP MESSAGE Requests从⼀个蜂窝⽹络到另⼀个蜂窝⽹络,这些SIP请求应当使⽤MIME类型“application/vnd.3gpp.sms”6种PDU介绍:1.SMS-DELIVER,包含从SC到MS的消息(基站发给⼿机的短信)。

2.SMS-DELIVER-REPORT,包含a)失败原因(如果需要的话)b) 对于SMS-DELIVER或SMS-STATUSREPORT的确认3. SMS-SUBMIT,包含从MS到SC的消息(从⼿机发出到基站的短信)。

4. SMS-SUBMIT-REPORT,包含a)失败原因(如果需要的话)b) 对于SMS-SUBMIT或SMS-COMMAND的确认5. SMS-STATUS-REPORT,包含从SC到MS的状态报告。

6. SMS-COMMAND,包含从MS到SC的命令。

GSM 7 bit Default Alphabet每个字符代表7位,参阅3GPP TS 23.038 或 ETSI GSM 03.38.7bit 的编码⽅式规则:7bit编码是把所有8bit 数据的⾼位去掉,形成7bit 数据,接下来将7bit数据的第⼆个字节的最低位,移到第⼀个字字节的最⾼位形第⼀个新的8位数据,再把第三个字节的最后两位移到第⼆个字节的最⾼位形第⼆个新的数据,以此类推,最后⼀个不⾜8位的7bit 数据全部⽤0补充形成⼀个新的8bit数据。

MS的解析原理及规律

MS的解析原理及规律

MS的解析原理及规律
一、基本原理
短信猫(SMS)是一种移动通信技术,它可以将短信发送到接收者的
移动设备上。

短信猫的基本原理是使用可移动的短信猫软件,将发送者的
短信文本内容转换成简短的二进制码,然后通过移动网络发送到接收者的
移动设备上。

接收者的移动设备再把短信文本内容解码为发送者原来的文本。

二、短信码的格式
短信猫根据GSM标准,将短信文本内容转换为7位或8位的二进制码,也叫做短信码(SMSC)。

这种短信码格式如下:
1、7位码(7Bits):它的码长为7位,每7位码对应一个字符,每
八个字节对应14个码字,每条短信最多可包含140个字符,一共可以发
送980个码字;
2、8位码(8Bits):它的码长为8位,每8位码对应一个字符,每
八个字节对应16个码字,每条短信最多可包含160个字符,一共可以发
送1120个码字;
三、编码过程
短信猫会将原始短信文本内容编码成7位或8位短信码,通常会按照
固定的规则来编码:
1、大写字符->7位码
2、小写字符->7位码
3、数字->7位码
4、标点符号->7位码
5、特殊字符->8位码
四、解码过程
1、接收端的移动设备会将收到的短信码通过反转编码的规则进行解码。

手机短信编码

手机短信编码

0891683108506405F011500B813168934922F60008FF084E2D56FD79FB52A8。其中,下划线部 分为 SMSC 部分,剩余的为 TPDU 部分。红色是编码后的短信中心号码,绿色是编码后的 目标号码,蓝色是编码后的信息内容。
1 SMSC 的格式
1.1 地址长度 一个字节,表示地址类型和地址值所占的字节数。 1.2 地址类型 一个字节,如下定义:
手机短信编码
短信息收发有关的规范主要包括 GSM 03.38、GSM 03.40 和 GSM 07.05。前二者着重描述 SMS 的技术实现(含编码方式),后者则规定了 SMS 的 DTE­DCE 接口标准(AT 命令集)。短信息的收发共 有三钟方式:Block 方式, Text 方式和 PDU 方式。Block 方式目前很少用;Text 方式是纯文本方式, 可使用不同的字符集,从技术上说也可用于发送中文短信息,但国内手机基本上不支持,主要用 于欧美地区;PDU 方式被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式。 PDU 串表面上是一串 ASCII 码,由‘ 0’­‘9’、‘A’­‘F’这些数字和字母组成。它们是 8 位字节 的十六进制数。PDU 串不仅包含可显示的消息本身,还包含很多其它信息,如 SMS 服务中心号 码、目标号码、编码方式等。PDU 方式下可以采用三种编码发送短信息:7 位编码、8 位编码和 16 位(UCS2)编码。 在 GSM 的介绍中,PDU 由两部分组成:短信息中心地址(SMSC)和传输协议数据单元 (Transfer Protocol Data Unit)。下面以实例介绍 PDU 数据格式。短信中心号码为:+ 8613800546500,目标地址为:13863994226,短信内容为:中国移动。短信编码为:

手机短信息SMS开发—编码,解码

手机短信息SMS开发—编码,解码

手机短信息SMS开发—编码,解码一起学习1、英文编码缺省的GSM字符集为7位编码,ASCII码为8位编码,编码就是将8位ASCII编码转换为7位编码。

例如:1234 编码后得到31D98C062进制表示8位编码00110001 00110010 00110011 001101007位编码00110001 11011001 10001100 00000110通过例子可以看出,将ascii8位编码的Bit8去掉,依次将下7位编码的后几位逐次移到前面,形成新的8位编码。

以下是C Builder的实现代码:String __stdcall EncodeEnglish(String InputStr){int n,len,cur;String tempstr,returnstr;unsigned char mid1[2],mid2[2];len=InputStr.Length();n=0;for(int i=1;i<=len;i ){if (i<len){strcpy(mid1,InputStr.SubString(i,1).c_str());strcpy(mid2,InputStr.SubString(i 1,1).c_str());cur=(mid1[0]>>n)|((mid2[0]<<(7-n))& 0xff);}else{strcpy(mid1,InputStr.SubString(i,1).c_str());cur=(mid1[0]>>n)& 0x7f;}FmtStr(tempstr,"%2.2X",ARRAYOFCONST((cur)));returnstr=returnstr tempstr;n=(n 1)%7;if (n==0)i ;}return returnstr;}2、英文解码简单地说就是将7位字符编码转换为8为字符编码以下是C Builder的实现代码:int ReturnHex(int Value){switch (Value){case 0:Value=0x7f;break;case 1:Value=0x3f;break;case 2:Value=0x1f;break;case 3:Value=0x0f;break;case 4:Value=0x07;break;case 5:Value=0x03;break;case 6:Value=0x01;break;case 7:Value=0x00;// 本文转自C Builder研究- /article.asp?i=120&d=26k1a3 break;}return Value;}String __stdcall DecodeEnglish (String InputStr){unsigned char InStr[300];char OutStr[300];String str;int j=0,i=0;int Point=0;int temp;memset(InStr,0,301);memset(OutStr,0,301);for(int i=0;i<InputStr.Length();i=i 2){str="0x" InputStr.SubString(i 1,2);InStr[i/2]=StrToInt(str);}while(j<=InputStr.Length()/2){if(Point==0)OutStr[i]=InStr[j]&ReturnHex(Point);elseOutStr[i]=((InStr[j]&ReturnHex(Point))<<Point)|(InStr[j-1]>>(8-Point));if(Point%7==0&&Point!=0)Point=0;elsePoint=Point 1;i ;j=i-(i/8);}OutStr[12]=((InStr[12]&0x07)<<5)|(InStr[11]>>(8-5));return AnsiString(OutStr);}3、中文编码中文编码较为简单,就是将GB2312的中文编码转换为代码页为CP936的Unicode编码即可以下是C Builder的实现代码String EncodeChinese(String InputStr){int cur;String tempstr,returnstr;WideString ws;wchar_t mid[2];ws=WideString(InputStr);for(int i=1;i<=ws.Length();i ){wcscpy(mid,ws.SubString(i,1).c_bstr());cur=mid[0];FmtStr(tempstr,"%4.4X",ARRAYOFCONST((cur)));returnstr=returnstr tempstr;}return returnstr;}4、中文解码将代码页为CP936的Unicode编码转换为GB2312的中文编码即可以下是C Builder的实现代码String DecodeChinese(String InputStr){wchar_t Buf[300];for(int i=0;i<InputStr.Length();i=i 4){Buf[i/4]=StrToInt("0x" InputStr.SubString(i 1,4));}Buf[InputStr.Length()/4]=0;return WideCharToString(Buf);}ChangNing(Redpower)changning@2001-8-7 1、英文编码缺省的GSM字符集为7位编码,ASCII码为8位编码,编码就是将8位ASCII编码转换为7位编码。

GSM短信发送PDU编码解码C++消息队列调用

GSM短信发送PDU编码解码C++消息队列调用

GSM短信发送PDU编码解码C++消息队列调用2009-04-20 14:17//SmsTraffic.h#include "SendMsg.h"#define MAX_SM_SEND 128 // 发送队列长度#define MAX_SM_RECV 128 // 接收队列长度enum ThreadState{stBeginRest, // 开始休息/延时stContinueRest, // 继续休息/延时stSendMessageRequest, // 发送短消息stSendMessageResponse, // 读取短消息列表到缓冲区stSendMessageWaitIdle, // 发送不成功,等待GSM就绪stReadMessageRequest, // 发送读取短消息列表的命令stReadMessageResponse, // 读取短消息列表到缓冲区stDeleteMessageRequest, // 删除短消息stDeleteMessageResponse, // 删除短消息stDeleteMessageWaitIdle, // 删除不成功,等待GSM就绪stExitThread // 退出} ; // 处理过程的状态class CSmsTraffic{public:CSmsTraffic();virtual ~CSmsTraffic();int m_nSendIn; // 发送队列的输入指针int m_nSendOut; // 发送队列的输出指针int m_nRecvIn; // 接收队列的输入指针int m_nRecvOut; // 接收队列的输出指针SM_PARAM m_SmSend[MAX_SM_SEND]; // 发送短消息队列SM_PARAM m_SmRecv[MAX_SM_SEND]; // 接收短消息队列CRITICAL_SECTION m_csSend; // 与发送相关的临界段CRITICAL_SECTION m_csRecv; // 与接收相关的临界段ThreadState m_State; //线程状态HANDLE m_hKillThreadEvent; // 通知子线程关闭的事件HANDLE m_hThreadKilledEvent; // 子线程宣告关闭的事件void PutSendMessage(SM_PARAM* pSmParam); // 将短消息放入发送队列BOOL GetSendMessage(SM_PARAM* pSmParam); // 从发送队列中取一条短消息void PutRecvMessage(SM_PARAM* pSmParam, int nCount); // 将短消息放入接收队列BOOL GetRecvMessage(SM_PARAM* pSmParam); // 从接收队列中取一条短消息//static UINT SmThread(LPVOID lpParam); // 短消息收发处理子线程static DWORD WINAPI SmThread(LPVOID lpParam); // 短消息收发处理子线程};//SmsTraffic.cpp#include "StdAfx.h"#include "SmsTraffic.h"#include "SendMsg.h"#include <time.h>///////////////////////////////////////////////////////////////////// /// Construction/Destruction///////////////////////////////////////////////////////////////////// /CSmsTraffic::CSmsTraffic(){m_nSendIn = 0;m_nSendOut = 0;m_nRecvIn = 0;m_nRecvOut = 0;m_hKillThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);m_hThreadKilledEvent = CreateEvent(NULL, TRUE, FALSE, NULL);InitializeCriticalSection(&m_csSend);InitializeCriticalSection(&m_csRecv);// 启动子线程//AfxBeginThread(SmThread, this, THREAD_PRIORITY_NORMAL); CreateThread(NULL,0,SmThread,(LPVOID)this,0,NULL);}CSmsTraffic::~CSmsTraffic(){SetEvent(m_hKillThreadEvent); // 发出关闭子线程的信号WaitForSingleObject(m_hThreadKilledEvent, INFINITE); // 等待子线程关闭DeleteCriticalSection(&m_csRecv);CloseHandle(m_hKillThreadEvent);CloseHandle(m_hThreadKilledEvent);}// 将一条短消息放入发送队列void CSmsTraffic::PutSendMessage(SM_PARAM* pparam){EnterCriticalSection(&m_csSend);memcpy(&m_SmSend[m_nSendIn], pparam, sizeof(SM_PARAM));m_nSendIn++;if (m_nSendIn >= MAX_SM_SEND) m_nSendIn = 0;LeaveCriticalSection(&m_csSend);//printf("第%d条短信入队列\n",m_nSendIn);}// 从发送队列中取一条短消息BOOL CSmsTraffic::GetSendMessage(SM_PARAM* pparam){BOOL fSuccess = FALSE;EnterCriticalSection(&m_csSend);if (m_nSendOut != m_nSendIn){memcpy(pparam, &m_SmSend[m_nSendOut], sizeof(SM_PARAM));m_nSendOut++;if (m_nSendOut >= MAX_SM_SEND) m_nSendOut = 0;fSuccess = TRUE;//printf("读取队列中第%d条短信\n",m_nSendOut);}LeaveCriticalSection(&m_csSend);return fSuccess;}// 将短消息放入接收队列void CSmsTraffic::PutRecvMessage(SM_PARAM* pparam, int nCount) {for (int i = 0; i < nCount; i++){memcpy(&m_SmRecv[m_nRecvIn], pparam, sizeof(SM_PARAM));m_nRecvIn++;if (m_nRecvIn >= MAX_SM_RECV) m_nRecvIn = 0;pparam++;}LeaveCriticalSection(&m_csRecv);}// 从接收队列中取一条短消息BOOL CSmsTraffic::GetRecvMessage(SM_PARAM* pparam){BOOL fSuccess = FALSE;EnterCriticalSection(&m_csRecv);if (m_nRecvOut != m_nRecvIn){memcpy(pparam, &m_SmRecv[m_nRecvOut], sizeof(SM_PARAM));m_nRecvOut++;if (m_nRecvOut >= MAX_SM_RECV) m_nRecvOut = 0;fSuccess = TRUE;}LeaveCriticalSection(&m_csRecv);return fSuccess;}DWORD WINAPI CSmsTraffic::SmThread(LPVOID lParam){SendMsg s_msg;//BOOL sendFlag = false; //发送是否成功CSmsTraffic* p=(CSmsTraffic *)lParam; // thisint nMsg; // 收到短消息条数int nDelete; // 目前正在删除的短消息编号SM_BUFF buff; // 接收短消息列表的缓冲区SM_PARAM param[256]; // 发送/接收短消息缓冲区//CTime tmOrg, tmNow; // 上次和现在的时间,计算超时用time_t tmOrg;time_t tmNow;int diffTime; //上次和现在的时间差// 初始状态p->m_State = stBeginRest;// 发送和接收处理的状态循环while (p->m_State != stExitThread){switch(p->m_State){case stBeginRest:// TRACE("State=stBeginRest\n");//tmOrg = CTime::GetCurrentTime();time(&tmOrg);//printf("tmOrg=%s\n",asctime(localtime(&tmOrg)));p->m_State = stContinueRest;break;case stContinueRest:// TRACE("State=stContinueRest\n");Sleep(300);//tmNow = CTime::GetCurrentTime();time(&tmNow);diffTime = static_cast<int> (difftime(tmNow,tmOrg));//printf("tmNow=%s\n",asctime(localtime(&tmNow)));if (p->GetSendMessage(&param[0])){p->m_State = stSendMessageRequest; // 有待发短消息,就不休息了}else if (diffTime >= 5) // 待发短消息队列空,休息5秒 {p->m_State = stReadMessageRequest; // 转到读取短消息状态}break;case stSendMessageRequest:// TRACE("State=stSendMessageRequest\n");s_msg.gsmSendMessage(&param[0]);memset(&buff, 0, sizeof(buff));//tmOrg = CTime::GetCurrentTime();time(&tmOrg);p->m_State = stSendMessageResponse;break;case stSendMessageResponse:// TRACE("State=stSendMessageResponse\n");Sleep(100);//tmNow = CTime::GetCurrentTime();time(&tmNow);switch (s_msg.gsmGetResponse(&buff)){case GSM_OK:// TRACE(" GSM_OK %d\n", tmNow - tmOrg);//printf("Send Success!\n");p->m_State = stBeginRest;break;case GSM_ERR:// TRACE(" GSM_ERR %d\n", tmNow - tmOrg);p->m_State = stSendMessageWaitIdle;break;default:// TRACE(" GSM_WAIT %d\n", tmNow - tmOrg);diffTime = static_cast<int> (difftime(tmNow,tmOrg));if (diffTime >= 10) // 10秒超时{// TRACE(" Timeout!\n");p->m_State = stSendMessageWaitIdle;}break;}break;case stSendMessageWaitIdle:Sleep(500);p->m_State = stSendMessageRequest; // 直到发送成功为止break;case stReadMessageRequest:// TRACE("State=stReadMessageRequest\n");s_msg.gsmReadMessageList();memset(&buff, 0, sizeof(buff));//tmOrg = CTime::GetCurrentTime();time(&tmOrg);p->m_State = stReadMessageResponse;break;case stReadMessageResponse:// TRACE("State=stReadMessageResponse\n");Sleep(100);//tmNow = CTime::GetCurrentTime();time(&tmNow);switch (s_msg.gsmGetResponse(&buff)){case GSM_OK:// TRACE(" GSM_OK %d\n", tmNow - tmOrg);nMsg = s_msg.gsmParseMessageList(param, &buff);if (nMsg > 0){p->PutRecvMessage(param, nMsg);nDelete = 0;p->m_State = stDeleteMessageRequest;}else{p->m_State =stBeginRest;}break;case GSM_ERR:// TRACE(" GSM_ERR %d\n", tmNow - tmOrg);p->m_State = stBeginRest;break;default:// TRACE(" GSM_WAIT %d\n", tmNow - tmOrg);diffTime = static_cast<int> (difftime(tmNow,tmOrg));if (diffTime >= 15) // 15秒超时{// // TRACE(" Timeout!\n");p->m_State = stBeginRest;}break;}break;case stDeleteMessageRequest:// TRACE("State=stDeleteMessageRequest\n");if (nDelete < nMsg){s_msg.gsmDeleteMessage(param[nDelete].index);memset(&buff, 0, sizeof(buff));//tmOrg = CTime::GetCurrentTime();time(&tmOrg);p->m_State = stDeleteMessageResponse;}else{p->m_State = stBeginRest;}break;case stDeleteMessageResponse:// TRACE("State=stDeleteMessageResponse\n");Sleep(100);//tmNow = CTime::GetCurrentTime();time(&tmNow);switch (s_msg.gsmGetResponse(&buff)){case GSM_OK:// TRACE(" GSM_OK %d\n", tmNow - tmOrg);nDelete++;p->m_State = stDeleteMessageRequest;break;case GSM_ERR:// TRACE(" GSM_ERR %d\n", tmNow - tmOrg);p->m_State = stDeleteMessageWaitIdle;break;default:// TRACE(" GSM_WAIT %d\n", tmNow - tmOrg);diffTime = static_cast<int> (difftime(tmNow,tmOrg));if (diffTime >= 5) // 5秒超时{// // TRACE(" Timeout!\n");p->m_State = stBeginRest;}break;}break;case stDeleteMessageWaitIdle:// TRACE("State=stDeleteMessageWaitIdle\n");Sleep(500);p->m_State = stDeleteMessageRequest; // 直到删除成功为止break;}// 检测是否有关闭本线程的信号DWORD dwEvent = WaitForSingleObject(p->m_hKillThreadEvent, 20);if (dwEvent == WAIT_OBJECT_0) p->m_State = stExitThread;}// 置该线程结束标志SetEvent(p->m_hThreadKilledEvent);return 9999;}。

手机短信编码与长度限制

手机短信编码与长度限制

手机短信编码与长度限制手机短信收发有三种方式:Block方式、Text方式和PDU方式,前两种在国内很少使用,PDU格式则普遍支持。

内容总长度140个字节(1120位),支持采用三种编码方式:7-bit、8-bit和UCS2编码,7-bit编码——用于发送普通的ASCII字符,ASCII码表最大到0x7X,最高位为0,总7-bit,实际编码时则可把8-bit的最高位比特使用起来,所以可支持1120/7=160个字符;8-bit编码——用于发送数据消息,比如图片和铃声、二进制数据等,此类数据无法使用7-bit编码,因为那样会丢掉一位,也不能用下面UCS2编码,因为不符合UNICODE编码检查(范围)。

8-bit编码最多支持140个字节数据。

UCS2编码——用于发送Unicode字符,每个中文(韩文、日文),占用2字节,只要短信里包含这些多字节编码文字,那么即使还有英文,英文也需要安装UCS2编码,也占用2字节,所以,最多支持70个中文字(或中英混合短信)总之,只要含有中文(日文、韩文等),就需要使用多字节编码方式,若编码采用UCS2格式,1中文字占2字节,则可容纳70个中文字,如果是纯英文,将默认使用7bit编码方式(注意是7bit编码),则可容纳(140*8)/7=160个字符。

超过此长度的短信,目前的智能机平台都可以本地实现自动切分成多个短信后再逐一进行发送,长短信因为要涉及到协议头。

如果想通过短信发送非文本信息的数据,建议通过数据端口方式,而不是文本,否则文本短信的默认处理规则(7bit格式)可能会导致数据不完整或丢失。

PDU编码由以下部分组成(顺序连接):1.短信息中心地址长度——1字节。

2.短信息中心号码类型——1字节。

3.短信息中心号码——A设置的长度-B的长度。

4.文件头字节——1字节。

5.信息类型——1字节。

6.被叫号码长度——1字节。

7.被叫号码类型——1字节,取值同B。

8.被叫号码——长度由F中的数据决定。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

手机短信息SMS开发—编码,解码一起学习1、英文编码缺省的GSM字符集为7位编码,ASCII码为8位编码,编码就是将8位ASCII编码转换为7位编码。

例如:1234 编码后得到31D98C062进制表示8位编码00110001 00110010 00110011 001101007位编码00110001 11011001 10001100 00000110通过例子可以看出,将ascii8位编码的Bit8去掉,依次将下7位编码的后几位逐次移到前面,形成新的8位编码。

以下是C Builder的实现代码:String __stdcall EncodeEnglish(String InputStr){int n,len,cur;String tempstr,returnstr;unsigned char mid1[2],mid2[2];len=InputStr.Length();n=0;for(int i=1;i<=len;i ){if (i<len){strcpy(mid1,InputStr.SubString(i,1).c_str());strcpy(mid2,InputStr.SubString(i 1,1).c_str());cur=(mid1[0]>>n)|((mid2[0]<<(7-n))& 0xff);}else{strcpy(mid1,InputStr.SubString(i,1).c_str());cur=(mid1[0]>>n)& 0x7f;}FmtStr(tempstr,"%2.2X",ARRAYOFCONST((cur)));returnstr=returnstr tempstr;n=(n 1)%7;if (n==0)i ;}return returnstr;}2、英文解码简单地说就是将7位字符编码转换为8为字符编码以下是C Builder的实现代码:int ReturnHex(int Value){switch (Value){case 0:Value=0x7f;break;case 1:Value=0x3f;break;case 2:Value=0x1f;break;case 3:Value=0x0f;break;case 4:Value=0x07;break;case 5:Value=0x03;break;case 6:Value=0x01;break;case 7:Value=0x00;// 本文转自C Builder研究- /article.asp?i=120&d=26k1a3 break;}return Value;}String __stdcall DecodeEnglish (String InputStr){unsigned char InStr[300];char OutStr[300];String str;int j=0,i=0;int Point=0;int temp;memset(InStr,0,301);memset(OutStr,0,301);for(int i=0;i<InputStr.Length();i=i 2){str="0x" InputStr.SubString(i 1,2);InStr[i/2]=StrToInt(str);}while(j<=InputStr.Length()/2){if(Point==0)OutStr[i]=InStr[j]&ReturnHex(Point);elseOutStr[i]=((InStr[j]&ReturnHex(Point))<<Point)|(InStr[j-1]>>(8-Point));if(Point%7==0&&Point!=0)Point=0;elsePoint=Point 1;i ;j=i-(i/8);}OutStr[12]=((InStr[12]&0x07)<<5)|(InStr[11]>>(8-5));return AnsiString(OutStr);}3、中文编码中文编码较为简单,就是将GB2312的中文编码转换为代码页为CP936的Unicode编码即可以下是C Builder的实现代码String EncodeChinese(String InputStr){int cur;String tempstr,returnstr;WideString ws;wchar_t mid[2];ws=WideString(InputStr);for(int i=1;i<=ws.Length();i ){wcscpy(mid,ws.SubString(i,1).c_bstr());cur=mid[0];FmtStr(tempstr,"%4.4X",ARRAYOFCONST((cur)));returnstr=returnstr tempstr;}return returnstr;}4、中文解码将代码页为CP936的Unicode编码转换为GB2312的中文编码即可以下是C Builder的实现代码String DecodeChinese(String InputStr){wchar_t Buf[300];for(int i=0;i<InputStr.Length();i=i 4){Buf[i/4]=StrToInt("0x" InputStr.SubString(i 1,4));}Buf[InputStr.Length()/4]=0;return WideCharToString(Buf);}ChangNing(Redpower)changning@2001-8-7 1、英文编码缺省的GSM字符集为7位编码,ASCII码为8位编码,编码就是将8位ASCII编码转换为7位编码。

例如:1234 编码后得到31D98C062进制表示8位编码00110001 00110010 00110011 001101007位编码00110001 11011001 10001100 00000110通过例子可以看出,将ascii8位编码的Bit8去掉,依次将下7位编码的后几位逐次移到前面,形成新的8位编码。

以下是C Builder的实现代码:String __stdcall EncodeEnglish(String InputStr){int n,len,cur;String tempstr,returnstr;unsigned char mid1[2],mid2[2];len=InputStr.Length();n=0;for(int i=1;i<=len;i ){if (i<len){strcpy(mid1,InputStr.SubString(i,1).c_str());strcpy(mid2,InputStr.SubString(i 1,1).c_str());cur=(mid1[0]>>n)|((mid2[0]<<(7-n))& 0xff);}else{strcpy(mid1,InputStr.SubString(i,1).c_str());cur=(mid1[0]>>n)& 0x7f;}FmtStr(tempstr,"%2.2X",ARRAYOFCONST((cur))); returnstr=returnstr tempstr;n=(n 1)%7;if (n==0)i ;}return returnstr;}2、英文解码简单地说就是将7位字符编码转换为8为字符编码以下是C Builder的实现代码:int ReturnHex(int Value){switch (Value){case 0:Value=0x7f;break;case 1:Value=0x3f;break;case 2:Value=0x1f;break;case 3:Value=0x0f;break;case 4:Value=0x07;break;case 5:Value=0x03;break;case 6:Value=0x01;break;case 7:Value=0x00;// 本文转自C Builder研究- /article.asp?i=120&d=26k1a3 break;}return Value;}String __stdcall DecodeEnglish (String InputStr){unsigned char InStr[300];char OutStr[300];String str;int j=0,i=0;int Point=0;int temp;memset(InStr,0,301);memset(OutStr,0,301);for(int i=0;i<InputStr.Length();i=i 2){str="0x" InputStr.SubString(i 1,2);InStr[i/2]=StrToInt(str);}while(j<=InputStr.Length()/2){if(Point==0)OutStr[i]=InStr[j]&ReturnHex(Point);elseOutStr[i]=((InStr[j]&ReturnHex(Point))<<Point)|(InStr[j-1]>>(8-Point));if(Point%7==0&&Point!=0)Point=0;elsePoint=Point 1;i ;j=i-(i/8);}OutStr[12]=((InStr[12]&0x07)<<5)|(InStr[11]>>(8-5));return AnsiString(OutStr);}3、中文编码中文编码较为简单,就是将GB2312的中文编码转换为代码页为CP936的Unicode编码即可以下是C Builder的实现代码String EncodeChinese(String InputStr){int cur;String tempstr,returnstr;WideString ws;wchar_t mid[2];ws=WideString(InputStr);for(int i=1;i<=ws.Length();i ){wcscpy(mid,ws.SubString(i,1).c_bstr());cur=mid[0];FmtStr(tempstr,"%4.4X",ARRAYOFCONST((cur)));returnstr=returnstr tempstr;}return returnstr;}4、中文解码将代码页为CP936的Unicode编码转换为GB2312的中文编码即可以下是C Builder的实现代码String DecodeChinese(String InputStr){wchar_t Buf[300];for(int i=0;i<InputStr.Length();i=i 4){Buf[i/4]=StrToInt("0x" InputStr.SubString(i 1,4));}Buf[InputStr.Length()/4]=0;return WideCharToString(Buf);}ChangNing(Redpower) changning@。

相关文档
最新文档