|
昨天简单完成了解码部分,今天加入编码部分(同一个类中)。方式和编码部分类似,利用属性对字段访问的特点,把解码程序写在属性访问部分。解码的函数只需读取这些属性值即可完成PDU解码工作。
手机或短信收发设备接收到的PDU字符串包含SCA、PDU-Type、OA、PID、DCS、SCTS、UDL、UD八个部分,每个部分包含对应字段和属性,字段中存储PDU格式编码对应段的字符串(函数先把对应字符串存入对应字段),属性读取过程写入代码,读取的值即为解码后的数据(短信内容、手机号码等)。
从PDU获取信息需读出(解码)四部分:SCA、OA、SCTS、UD,以下分别对其讲解。
有关收到信息PDU格式解析参考:
PDU格式短信编码的原理
示例PDU串:从15118131494收到一条短信,内容“你好”。
0891683110402505F0240BA15111181394F4000801112081600423044F60597D
SCA(短消息服务中心)部分解码:
字段:serviceCenterAddress;属性:ServiceCenterAddress。
解码时,先把SCA部分PDU串(0891683110402505F0)写入字段serviceCenterAddress。属性访问器get部分完成解码工作。get部分代码:- get
- {
- int len = Convert.ToInt32(serviceCenterAddress.Substring(0, 2)); //获取SCA长度
- string result = serviceCenterAddress.Substring(4, len - 4); //去掉起头部分
- //ParityChange函数见上一篇的编码
- result = ParityChange(result); //奇偶互换
- result = result.TrimEnd('F', 'f'); //去掉结尾F
- return result;
- }
复制代码 这样,读取ServiceCenterAddress属性即可得到短消息中心地址。程序可读取示例消息中心:8613010452500
字段:originatorAddress;属性:OriginatorAddress。
解码时,先把OA部分PDU串(0BA15111181394F4)写入字段originatorAddress。同样,从属性读取到的即为发送方的手机号码。
对应get访问器代码:
- get
- {
- int len = Convert.ToInt32(originatorAddress.Substring(0, 2),16); //十六进制字符串转为整形数据
- string result = string.Empty;
- if (len % 2 == 1) //号码长度是奇数,长度加1 编码时加了F
- {
- len++;
- }
- result = originatorAddress.Substring(4, len); //去掉头部
- result = ParityChange(result).TrimEnd('F', 'f'); //奇偶互换,并去掉结尾F
-
- return result;
- }
复制代码
这样,读取OriginatorAddress属性即可得到短消息中心地址。程序可读取示例消息中心:15118131494
字段:serviceCenterTimeStamp;属性:ServiceCenterTimeStamp。
解码时,先把SCTS部分PDU串(01112081600423)写入字段serviceCenterTimeStamp。同样,从属性读取到的即为消息中心收到信息的时间。
对应get访问器代码:
- get
- {
- string result = ParityChange(serviceCenterTimeStamp); //奇偶互换
- result = "20" + result.Substring(0, 12); //年加开始的“20”
-
- return result;
- }
复制代码
读取ServiceCenterTimeStamp属性即可得到时间字符串:20101102180640 代表:2010-11-02 18:06:44
字段:userData;属性:UserData。
解码时,先把UD部分PDU串(4F60597D)写入字段UserData。同样,从属性读取到的即为短信内容。
对应get访问器代码:
- get
- {
- int len = Convert.ToInt32(userDataLenghth, 16) * 2;
- string result = string.Empty;
- //四个一组,每组译为一个USC2字符
- for (int i = 0; i < len; i += 4)
- {
- string temp = userData.Substring(i , 4);
-
- int byte1 = Convert.ToInt16(temp, 16);
-
- result += ((char)byte1).ToString();
- }
-
- return result;
- }
复制代码
访问UserData即得段内容。示例可得到短信内容:“你好”。
解码程序须将对应PDu编码的值赋给对应字段,然后读取各个属性即可完成解码:
- /// <summary>
- /// 完成手机或短信收发设备收到PDU格式短信的解码 暂时仅支持中文编码
- /// 未用DCS部分
- /// </summary>
- /// <param name="strPDU">短信PDU字符串</param>
- /// <param name="msgCenter">短消息服务中心 输出</param>
- /// <param name="phone">发送方手机号码 输出</param>
- /// <param name="msg">短信内容 输出</param>
- /// <param name="time">时间字符串 输出</param>
- public void PDUDecoder(string strPDU, out string msgCenter, out string phone, out string msg, out string time)
- {
- int lenSCA = Convert.ToInt32(strPDU.Substring(0, 2), 16) * 2 + 2; //短消息中心占长度
- serviceCenterAddress = strPDU.Substring(0, lenSCA);
-
- int lenOA = Convert.ToInt32(strPDU.Substring(lenSCA + 2, 2),16); //OA占用长度
- if (lenOA % 2 == 1) //奇数则加1 F位
- {
- lenOA++;
- }
- lenOA += 4; //加号码编码的头部长度
- originatorAddress = strPDU.Substring(lenSCA + 2, lenOA);
-
- serviceCenterTimeStamp = strPDU.Substring(lenSCA + lenOA + 6, 14);
-
- userDataLenghth = strPDU.Substring(lenSCA + lenOA + 20, 2);
- int lenUD = Convert.ToInt32(userDataLenghth, 16) * 2;
- userData = strPDU.Substring(lenSCA + lenOA + 22, lenUD);
-
- msgCenter = ServiceCenterAddress;
- phone = OriginatorAddress;
- msg = UserData;
- time = ServiceCenterTimeStamp;
- }
复制代码
调用程序pe.PDUDecoder("0891683110402505F0240BA15111181394F4000801112081600423044F60597D", out s1, out s2, out s3, out s4);(peDUEncoding pe=new PDUEncoding();)
输出:
s1:8613010452500
s2:15118131494
s2:你好
s3:20101102180640
成功!
至此编码部分简单完成
实现的比较简单,没有实现7bit及8bit部分编解码。有兴趣可以下载附件,自己添加。
项目工程.rar
(134.42 KB, 下载次数: 3134)
|
|