其实这个是非常有意义的。在GSM中用

解决方案 »

  1.   

    gsmString2Bytes();的函数在delphi中没有的。。在C中是什么意思呢?
      

  2.   

    gsmString2Bytes/gsmDecodeUcs2/gsmDecode8bit这些函数都是自己写的,不是系统的,不是Windows/Delphi的~~~~~~~~~~~~~~~~
      

  3.   

    汉字转PDU编码function Encode1(var s:String):String;
    var
      i,j,len:Integer;
      cur:Integer;
      t:String;
      ws:WideString;
    begin
      Result:='';
      ws:=s;
      len:=Length(ws);
      i:=1;j:=0;
      while i<=len do
      begin
          cur:=ord(ws[i]);
          //BCD转换
          FmtStr(t,'%4.4X',[cur]);
        Result:=Result+t;
        inc(i);
        //移位计数达到7位的特别处理
        j:=(j+1) mod 7;
      end;
    end;
      

  4.   

    pdu编码格式08 //短消息中心长度
    91 //短消息中心有国家编码 没有为81
    68 31 08 02 00 05 f0 //短消息中心
    31 //需要状态报告//不需为11
    00 //永远为00 //分割符
    0D //目标号码的长度14位
    91 //有国家编码//没有为81
    68 31 36 32 64 49 F0 //目标号码 +8613632346940
    00 //TP-PID.协议标识,一般为00,其他值大家知道的帮忙补充一下
    08 //是否免提//是为18
    A7 //有效期标志
    04 //正文4字节
    4F 60 59 7D //你好 短消息内容若没有短消息中心,编码为:
    00 //表示默认短消息中心
    31 //需要状态报告//不需为11
    00 //永远为00 //分割符
    0D //目标号码的长度14位
    91 //有国家编码//没有为81
    68 31 36 32 64 49 F0 //目标号码 +8613632346940
    00  //TP-PID.协议标识,一般为00,其他值大家知道的帮忙补充一下
    08 //是否免提//是为18
    A7 //有效期标志
    04 //正文4字节
    4F 60 59 7D //你好 短消息内容
      

  5.   

    找到其它的那一部分了,供大家分享..
    int gsmEncode7bit(const char* pSrc, unsigned char* pDst, int nSrcLength)
    {
        int nSrc;        // 源字符串的计数值
        int nDst;        // 目标编码串的计数值
        int nChar;       // 当前正在处理的组内字符字节的序号,范围是0-7
        unsigned char nLeft;    // 上一字节残余的数据
        
        // 计数值初始化
        nSrc = 0;
        nDst = 0;
        
        // 将源串每8个字节分为一组,压缩成7个字节
        // 循环该处理过程,直至源串被处理完
        // 如果分组不到8字节,也能正确处理
        while(nSrc<nSrcLength)
        {
            // 取源字符串的计数值的最低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-6
        unsigned char nLeft;    // 上一字节残余的数据
        
        // 计数值初始化
        nSrc = 0;
        nDst = 0;
        
        // 组内字节序号和残余数据初始化
        nByte = 0;
        nLeft = 0;
        
        // 将源数据每7个字节分为一组,解压缩成8个字节
        // 循环该处理过程,直至源数据被处理完
        // 如果分组不到7字节,也能正确处理
        while(nSrc<nSrcLength)
        {
            // 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节
            *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以下也排布了一些可打印字符,但英文字母、阿拉伯数字和常用符号的位置两者是一样的。用上面介绍的算法收发纯英文短消息,一般情况应该是够用了。如果是法语、德语、西班牙语等,含有 “&aring;”、 “é”这一类字符,则要按上面编码的输出去查表,请参阅GSM 03.38的规定。8-bit编码其实没有规定什么具体的算法,不需要介绍。UCS2编码是将每个字符(1-2个字节)按照ISO/IEC10646的规定,转变为16位的Unicode宽字符。在Windows系统中,特别是在2000/XP中,可以简单地调用API 函数实现编码和解码。如果没有系统的支持,比如用单片机控制手机模块收发短消息,只好用查表法解决了。Windows环境下,用C实现UCS2编码和解码的算法如下:// UCS2编码
    // pSrc: 源字符串指针
    // pDst: 目标编码串指针
    // nSrcLength: 源字符串长度
    // 返回: 目标编码串长度
    int gsmEncodeUcs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
    {
        int nDstLength;        // UNICODE宽字符数目
        WCHAR wchar[128];      // UNICODE串缓冲区
        
        // 字符串-->UNICODE串
        nDstLength = ::MultiByteToWideChar(CP_ACP, 0, pSrc, nSrcLength, wchar, 128);
        
        // 高低字节对调,输出
        for(int i=0; i<nDstLength; i++)
        {
            // 先输出高位字节
            *pDst++ = wchar[i] >> 8;
            // 后输出低位字节
            *pDst++ = wchar[i] & 0xff;
        }
        
        // 返回目标编码串长度
        return nDstLength * 2;
    }
        
    // UCS2解码
    // pSrc: 源编码串指针
    // pDst: 目标字符串指针
    // nSrcLength: 源编码串长度
    // 返回: 目标字符串长度
    int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
    {
        int nDstLength;        // UNICODE宽字符数目
        WCHAR wchar[128];      // UNICODE串缓冲区
        
        // 高低字节对调,拼成UNICODE
        for(int i=0; i<nSrcLength/2; i++)
        {
            // 先高位字节
            wchar[i] = *pSrc++ << 8;
        
            // 后低位字节
            wchar[i] |= *pSrc++;
        }
        
        // UNICODE串-->字符串
        nDstLength = ::WideCharToMultiByte(CP_ACP, 0, wchar, nSrcLength/2, pDst, 160, NULL, NULL);
        
        // 输出字符串加个结束符    
        pDst[nDstLength] = '\0';    
        
        // 返回目标字符串长度
        return nDstLength;
    }用以上编码和解码模块,还不能将短消息字符串编码为PDU串需要的格式,也不能直接将PDU串中的用户信息解码为短消息字符串,因为还差一个在可打印字符串和字节数据之间相互转换的环节。可以循环调用sscanf和sprintf函数实现这种变换。下面提供不用这些函数的算法,它们也适用于单片机、DSP编程环境。// 可打印字符串转换为字节数据
    // 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
    // pSrc: 源字符串指针
    // pDst: 目标数据指针
    // nSrcLength: 源字符串长度
    // 返回: 目标数据长度
    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++;
        }
        
        // 返回目标数据长度
        returnnSrcLength / 2;
    }
        
    // 字节数据转换为可打印字符串
    // 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01" 
    // pSrc: 源数据指针
    // pDst: 目标字符串指针
    // nSrcLength: 源数据长度
    // 返回: 目标字符串长度
    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++;
        }
        
        // 输出字符串加个结束符
        *pDst = '\0';
        
        // 返回目标字符串长度
        return nSrcLength * 2;
    }