C#PDU编码8BIT加密解密函数和短信GSM加密解密用到的不错的一个类

原文地址:http://www.wangchao.net.cn/bbsdetail_50338.html

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmsTest
{
    /// <summary>
    /// By popcorn 2004.5。
    /// cnpopcorn@hotmail.com
    /// </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
            {
                //短信息中心
                int iLength = int.Parse(s.Substring(0, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                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.AllowHexSpecifier);
                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;
                else
                    code = 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)
            {
                byte bSrc = byte.Parse(s.Substring(i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
                // 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节
                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.AllowHexSpecifier);
            }
            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.AllowHexSpecifier);
            }
            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.AllowHexSpecifier);
                buf[i / 2 + 1] = byte.Parse(s.Substring(i, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
            }
            return Encoding.Unicode.GetString(buf);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的C语言程序,用于将文本消息转换为PDU格式: ``` #include <stdio.h> #include <string.h> void encode_pdu(const char* message, const char* phone_number, const char* center_number, char* pdu) { int i, j; int message_length = strlen(message); int phone_number_length = strlen(phone_number); int center_number_length = strlen(center_number); char hex_length[3]; char pdu_header[32]; char pdu_message[256]; char pdu_phone_number[32]; char pdu_center_number[32]; // 将消息长度转换为16进制字符串 sprintf(hex_length, "%02X", message_length); // 将消息编码方式设置为7位ASCII码 strcpy(pdu_header, "00"); // 将短信心号码转换为BCD码 for (i = 0, j = 0; i < center_number_length; i += 2, j++) { pdu_center_number[j] = ((center_number[i] - '0') << 4) | (center_number[i + 1] - '0'); } if (center_number_length % 2 == 1) { pdu_center_number[j - 1] |= 0xF0; j++; } pdu_center_number[j] = '\0'; // 将手机号码转换为BCD码 for (i = 0, j = 0; i < phone_number_length; i += 2, j++) { pdu_phone_number[j] = ((phone_number[i + 1] - '0') << 4) | (phone_number[i] - '0'); } if (phone_number_length % 2 == 1) { pdu_phone_number[j - 1] |= 0xF0; j++; } pdu_phone_number[j] = '\0'; // 将消息转换为7位ASCII码 for (i = 0; i < message_length; i++) { pdu_message[i * 2] = (message[i] & 0x7F); pdu_message[i * 2 + 1] = ((message[i] >> 7) & 0x01); } pdu_message[i * 2] = '\0'; // 将PDU数据按顺序拼接起来 sprintf(pdu, "%s%s%s%s%s%s", pdu_header, hex_length, pdu_center_number, "00", "0A", pdu_phone_number); strcat(pdu, "00"); // TP-PID strcat(pdu, "00"); // TP-DCS strcat(pdu, "00"); // TP-VP strcat(pdu, pdu_message); } int main() { char pdu[512]; encode_pdu("hello", "13800138000", "+8613800000500", pdu); printf("%s\n", pdu); return 0; } ``` 在这个程序,`encode_pdu`函数接受文本消息、手机号码和短信心号码作为参数,并将PDU格式编码后的数据写入`pdu`数组。程序使用了C语言的字符串操作函数,例如`strlen`、`strcpy`和`strcat`。 在函数,先计算出消息长度的16进制表示,并将消息编码方式设置为7位ASCII码。然后将短信心号码和手机号码分别转换为BCD码,并在末尾添加F或0F。接下来将消息转换为7位ASCII码,并将PDU数据按顺序拼接起来,最后将PDU数据写入`pdu`数组。 在`main`函数调用`encode_pdu`函数,将文本消息、手机号码和短信心号码作为参数传递给它,并打印出生成的PDU数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值