SMS中用Unicode编码发送中文

原创 2003年03月08日 14:59:00

SMS中用Unicode编码发送中文

 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

作者:    陈轶飞

最后更新:   2003-03-08

关键词:  SMS、PDU、Unicode、GB2312、linux、编码转换

 

       SMS是由Esti 所制定的一个规范(GSM 03.40 GSM 03.38)。有两种方式来发送和接收SMS消息:文本模式或者PDUprotocol 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的规范,可以看这里:http://www.ascend-tech.com.cn/sustain/SMS_PDU-mode.pdf ,或者去wavecom的网站上找找看。

 

1、 GB2312 编码到Unicode 编码的转换

 

Redhat 7.3系统上,默认是用GB2312编码保存中文字符的(对于中英文混合的文本也是如此)。所以首先需要把 GB2312 编码的字符串转换到 Unicode编码的字符串。GB2312编码是一种多字节编码方式,对于中文,用2个字节表示,对于英文,用1个字节表示,就是英文的ascii码。(注:我没有仔细看过GB2312编码的规范,以上理解是实际开发中得出来的,不能保证正确性)。Unicode编码是双字节编码方式,对所有字符,都采用2个字节编码。在linux平台上,GB2312编码到Unicode编码的转换,可以有三种实现方式(或者更多):

1)、用 mbstowcs () 函数。就是多字节编码到宽字符的转换。我试过它,可以正确的转换,但是这个函数可能不是很可靠。

 

2)、用 GB2312 à Unicode 的转换表,手动查表转换。网上有这样的转换表,你需要对每一个GB2312字符,根据它是中文字符还是英文字符,分别转换。

 

3)、用 iconv () 函数。这可能是linux上的标准的方法,不仅可以转换GB2312Unicode,还可以在任意的两种编码之间转换(前提是linux系统要支持这些编码)。

首先要用 iconv_open() 打开一个转换句柄,指定两种转换前的编码和转换后的编码。

然后用 icnov() 作转换。最后用 iconv_close()关闭句柄,释放资源。

 

 

 

 

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />

#include <iconv.h>

 

#define BUFLEN 200

char inbuf[BUFLEN];

char outbuf[BUFLEN];

char* pin = inbuf;

char* pout = outbuf;

 

打开文件,读入GB2312数据到inbuf,数据长度为 len

 

int inleft = len;

int outleft = BUFLEN;

 

iconv_t cd;

if((cd = iconv_open(“gb2312”, “unicode”)) == (iconv_t)-1)

        return –1;

if(iconv(cd, &pin, &inleft, &pout, &outleft) == (size_t)-1)

        return –1;

iconv_close(cd);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


使用 iconv () 时,需要注意参数的使用,inleft 是输入缓冲区数据数据长度,outleft是输出缓冲区大小。(需要保证输出缓冲区足够大)。

转换以后,outleft outbuf中空闲空间的大小,所以 BUFLEN-outleft 才是真正的Unicode数据长度。

注意:不论是GB2312编码,还是Unicode编码,在内存中都是一些字节序列,所以我们可以统一用 类型为 char(或者unsigned char)的字符数组来保存。所以,BUFLEN-outleft 字符(char)个数,而不是Unicode字符个数。

 

 

2、  Unicode 编码到 16-bit 编码的转换

 

在得到 Unicode编码以后,还需要转换到 PDU 16-bit 编码,才可以正确的发送。在这个转换过程中,需要注意两点:

1)、Unicode 编码最开始的 0xFEFF标志要被去除,在0xFEFF之后的内容,才是真正的Unicode字符。(至于为什么有这个0xfeff标志,知道的朋友告诉我一声,呵呵)。

 

2)、Unicode 是双字节字符,由于我的系统是小端字节序(little-endian),也就是说,在存储的时候,是先低位,后高位,例如“中”的Unicode编码是 0x4E2D,存储的时候是 2D4E,在转换到 16-bit编码的时候,要注意这个顺序的不同。当然,如果你的系统是大端字节序(big-endian),那么就不用这样做了。

 

3)、为了将0x4E2D Unicode编码转换到 “4E2D” 16-bit编码,可以用 sprintf(buf,  “%02X”,  outbuf[i]) 对每一个字节作转换。

 

 

3、正确计算16-bit 编码的消息体长度

       PDU规范中,需要包括消息体的长度,这里你要小心计算。

 

4、正确设置 First-Octet 、TP-MR、TP-PID、TP-DCS、TP-VP

 

PDU格式中,First-Octet TP-MRTP-PIDTP-DCSTP-VP的设置正确与否,对能否发送 Unicode 至关重要。根据协议规范以及我的调试结果,以上几个标志的正确设置分别为(都是16进制):

First-Octet 11   

TP-MR       00

TP-PID       00

TP-DCS      08    (编码方式,16-bit

TP-VP               A7         

 

       经过以上步骤,已经可以做到发送中文字符了。

希望这篇文档,能为准备在linux下做短信开发的朋友提供一些帮助。

      

 

参考资料:

        An introduction to the SMS in PDU mode GSM Recommendation phase 2

汉字unicode编码范围

 GB2312编码:1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。 BIG5编码:台湾地区繁体中文标准字符...
  • gywtzh0889
  • gywtzh0889
  • 2017年05月02日 16:58
  • 1465

中文和Unicode编码互转

public class UnicodeUtil { /** * 字符串转换unicode */ public static String string2Unico...
  • aiynmimi
  • aiynmimi
  • 2016年09月23日 17:50
  • 533

贡献一段 GSM 发送汉字短信的 完整代码 其中包括了汉字转Unicode码转换函数

这段代码时很久之前写的 今天发出来 时回想当时的情景 非常的好玩,尤其在汉字转换为Unicode码的时候  好好玩 /* * mess.c * * Created on: 2013-3-5 ...
  • sfe1012
  • sfe1012
  • 2015年03月24日 21:14
  • 948

Unicode编码——中文和特殊字符的范围

编程中偶尔会遇到疑难杂项,比如:特殊字符。
  • leopadus
  • leopadus
  • 2017年04月03日 16:32
  • 1480

PHP中对汉字进行UNICODE编码和解码的功能

  • dongsg11200
  • dongsg11200
  • 2014年04月03日 18:00
  • 22474

中文转换成Unicode编码和Unicode编码转换成中文,Java代码实现

import java.util.Properties; public class Test { public static void main(String[] arg...
  • jdsjlzx
  • jdsjlzx
  • 2011年12月10日 01:01
  • 11395

Unicode编码区间

Unicode 字符编码表|汉字Unicode编码的区间为:0x4E00→0x9FA5(转) 十进制 十六进制  字符数 编码分类(中文) 编码分类(...
  • l464373218
  • l464373218
  • 2016年06月11日 00:26
  • 427

iOS技巧——解决iOS中的中文unicode编码问题

创建NSString的类别 ReplaceUnicode。 NSString+ReplaceUnicode.h
  • u013613377
  • u013613377
  • 2014年04月09日 14:51
  • 4520

Unicode编码和中文互转(JAVA实现)

//中文转Unicode public static String gbEncoding(final String gbString) { //gbString = "测试" ...
  • u010612373
  • u010612373
  • 2016年05月18日 09:16
  • 19275

Android- Unicode编码 和 汉字转换( java实现 , javascript实现)

1.回顾    好久没写文章了 , 不过最近在 弄自己的 个人博客 ,  还不错 , 使用 wordpress搭建而成的 . 还有就是 国庆假期 出去玩了, 该收收心了 .    欢迎访问: ...
  • LABLENET
  • LABLENET
  • 2015年10月08日 18:25
  • 3636
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SMS中用Unicode编码发送中文
举报原因:
原因补充:

(最多只允许输入30个字)