SMS中用Unicode编码发送中文的办法
2008-02-23 05:41:41来源:互联网 阅读 ()
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的规范,能够看这里: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上的标准的方法,不但能够转换GB2312到Unicode,还能够在任意的两种编码之间转换(前提是linux系统要支持这些编码)。
首先要用 iconv_open(), 打开一个转换句柄,指定两种转换前的编码和转换后的编码。
然后用 icnov() 作转换。最后用 iconv_close()关闭句柄,释放资源。
#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),那么就不用这样做了。
OK,关于如何将 0x4E2D 的Unicode编码转换到 “4E2D” 的16-bit编码,我就不多写了。
3、正确计算16-bit 编码的消息体长度
4、正确配置 First-Octet 、TP-MR、TP-PID、TP-DCS、TP-VP
在PDU格式中,First-Octet 、TP-MR、TP-PID、TP-DCS、TP-VP的配置正确和否,对能否发送 Unicode 至关重要。根据协议规范连同我的调试结果,以上几个标志的正确配置分别为(都是16进制):
First-Octet : 11
TP-MR : 00
TP-PID : 00
TP-DCS : 08 (编码方式,16-bit)
TP-VP : A7
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: Linux下C语言编程--时间概念
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash