?? 手機(jī)短信息sms開發(fā)—編碼和解碼.txt
字號:
手機(jī)短信息SMS開發(fā)—編碼和解碼
2002-07-04· · ··C++builder資源中心
上一頁 1 2 3
3、中文編碼
中文編碼較為簡單,就是將GB2312的中文編碼轉(zhuǎn)換為代碼頁為CP936的Unicode編碼即可
以下是C++Builder的實現(xiàn)代碼
String EncodeChinese(String InputStr)
{
int cur;
String tempstr,returnstr;
WideString ws;
wchar_t mid[2];
ws=WideString(InputStr);
for(int i=1;i<=ws.Length();i++)
{
wcscpy(mid,ws.SubString(i,1).c_bstr());
cur=mid[0];
FmtStr(tempstr,"%4.4X",ARRAYOFCONST((cur)));
returnstr=returnstr+tempstr;
}
return returnstr;
}
4、中文解碼
將代碼頁為CP936的Unicode編碼轉(zhuǎn)換為GB2312的中文編碼即可
以下是C++Builder的實現(xiàn)代碼
String DecodeChinese(String InputStr)
{
wchar_t Buf[300];
for(int i=0;i
{
Buf[i/4]=StrToInt("0x"+InputStr.SubString(i+1,4));
}
Buf[InputStr.Length()/4]=0;
return WideCharToString(Buf);
}
ChangNing(Redpower)
2、英文解碼
簡單地說就是將7位字符編碼轉(zhuǎn)換為8為字符編碼
以下是C++Builder的實現(xiàn)代碼:
int ReturnHex(int Value)
{
switch (Value)
{
case 0:
Value=0x7f;
break;
case 1:
Value=0x3f;
break;
case 2:
Value=0x1f;
break;
case 3:
Value=0x0f;
break;
case 4:
Value=0x07;
break;
case 5:
Value=0x03;
break;
case 6:
Value=0x01;
break;
case 7:
Value=0x00;
break;
}
return Value;
}
String __stdcall DecodeEnglish (String InputStr)
{
unsigned char InStr[300];
char OutStr[300];
String str;
int j=0,i=0;
int Point=0;
int temp;
memset(InStr,0,301);
memset(OutStr,0,301);
for(int i=0;i
{
str="0x"+InputStr.SubString(i+1,2);
InStr[i/2]=StrToInt(str);
}
while(j<=InputStr.Length()/2)
{
if(Point==0)
OutStr[i]=InStr[j]&ReturnHex(Point);
else
OutStr[i]=((InStr[j]&ReturnHex(Point))<>(8-Point));
if(Point%7==0&&Point!=0)
Point=0;
else
Point=Point+1;
i++;
j=i-(i/8);
}
OutStr[12]=((InStr[12]&0x07)<<5)|(InStr[11]>>(8-5));
return AnsiString(OutStr);
}
1、 英文編碼
缺省的GSM字符集為7位編碼,ASCII碼為8位編碼,編碼就是將8位ASCII編碼轉(zhuǎn)換為7位編碼。
例如:1234 編碼后得到31D98C06
2進(jìn)制表示
8位編碼 00110001 00110010 00110011 00110100
7位編碼 00110001 11011001 10001100 00000110
通過例子可以看出,將ascii8位編碼的Bit8去掉,依次將下7位編碼的后幾位逐次移到前面,形成新的8位編碼。
以下是C++Builder的實現(xiàn)代碼:
String __stdcall EncodeEnglish(String InputStr)
{
int n,len,cur;
String tempstr,returnstr;
unsigned char mid1[2],mid2[2];
len=InputStr.Length();
n=0;
for(int i=1;i<=len;i++)
{
if (i
{
strcpy(mid1,InputStr.SubString(i,1).c_str());
strcpy(mid2,InputStr.SubString(i+1,1).c_str());
cur=(mid1[0]>>n)|((mid2[0]<<(7-n))& 0xff);
}
else
{
strcpy(mid1,InputStr.SubString(i,1).c_str());
cur=(mid1[0]>>n)& 0x7f;
}
FmtStr(tempstr,"%2.2X",ARRAYOFCONST((cur)));
returnstr=returnstr+tempstr;
n=(n+1)%7;
if (n==0)
i++;
}
return returnstr;
}
目前手機(jī)短信息的應(yīng)用越來越廣泛,互聯(lián)網(wǎng)上提供短信息發(fā)送的站點也越來越多,但一些站點的服務(wù)并不盡如人意,往往發(fā)出去的短信息石沉大海。最可靠的發(fā)送方法當(dāng)然是用手中的手機(jī)了,如果設(shè)置了狀態(tài)報告,更能確切知道對方是否收到了此條信息。手機(jī)發(fā)送盡管比較可靠, 但也存在輸入麻煩、效率低的問題。本文介紹一種方法,只要手機(jī)能夠與電腦相連(通過紅外端口或用手機(jī)數(shù)據(jù)線連接串行口,同時手機(jī)支持GSM AT指令集),就可以通過自行編制的短信息發(fā)送軟件,實現(xiàn)短信息的發(fā)送。
現(xiàn)在市場上的大多數(shù)手機(jī)均支持類似于Modem控制的GSM AT指令集,該指令集是由諾基亞、愛立信、摩托羅拉和HP等廠家共同為GSM系統(tǒng)研制的,其中包含了對SMS(Short Message Service)的控制。
GSM AT相關(guān)指令的介紹
與SMS有關(guān)的GSM AT指令如表1所示:
(暫無)
表1 相關(guān)的GSM AT指令
對SMS的控制共有三種實現(xiàn)途徑:
Block Mode;
基于AT命令的Text Mode;
基于AT命令的PDU Mode。
Text Mode比較簡單,多款諾基亞手機(jī)均支持該模式。西門子的手機(jī)大多只支持PDU模式,PDU模式是發(fā)送或接收手機(jī)SMS信息的一種方法,短信息正文經(jīng)過十六進(jìn)制編碼后被傳送。目前,PDU已取代Block Mode,因此本文主要探討PDU模式的發(fā)送。
計算機(jī)和手機(jī)的通信
本文以西門子 S3568i為例,介紹如何實現(xiàn)短信息的發(fā)送。
數(shù)據(jù)線連接
首先,通過S3525數(shù)據(jù)線將手機(jī)與電腦串行口相連。然后,打開超級終端,選擇直接串行口連接,端口參數(shù)設(shè)為19200速率、無校驗、數(shù)據(jù)位8、停止位1。
紅外線連接
如果使用帶紅外端口的計算機(jī),可以設(shè)置與手機(jī)的無線連接。首先確認(rèn)計算機(jī)紅外端口已打開,并將手機(jī)的紅外線和收傳真數(shù)據(jù)功能打開,對接紅外端口,計算機(jī)系統(tǒng)托盤上應(yīng)當(dāng)出現(xiàn)一個紅外設(shè)備西門子S35(如果沒有安裝紅外監(jiān)視器,則不顯示)。然后,打開超級終端,選擇IrDa上的串行口。
連接測試
點擊超級終端工具條上的呼叫按鈕,輸入AT并回車,屏幕上如果出現(xiàn)OK則表明計算機(jī)與手機(jī)的連接成功,這時就可以輸入各類GSM AT指令了。
如:查詢手機(jī)廠家,輸入AT+CGMI=,屏幕顯示Siemens。
通常情況下,執(zhí)行測試命令A(yù)T+CMGS=?,如果返回OK,表明手機(jī)支持此指令。該指令的完整語法格式如下:
If PDU mode (+CMGF=0)+CMGS=PDU is given
如果短信息格式指令A(yù)T+CMGF返回的是0,則SMS格式為PDU模式,再執(zhí)行AT+CMGS=<數(shù)據(jù)長度>命令后,手機(jī)返回“>”符號并等待輸入,輸入PDU數(shù)據(jù)并以^Z或Esc鍵結(jié)束。
如果信息發(fā)送成功,則返回OK,并顯示信息號:
+CMGS:
如果發(fā)送失敗,則返回如下信息:
+CMS ERROR:
PDU數(shù)據(jù)格式的分析
下面通過對存儲在手機(jī)中的待發(fā)信息的分析,來介紹SMS PDU的數(shù)據(jù)格式。首先,用手機(jī)寫一條短信息,發(fā)送手機(jī)號碼為13605696031,信息內(nèi)容為“Hello World!”。通過執(zhí)行AT+CMGL=2可以讀出此條信息。
操作過程如下(斜體字符為響應(yīng)信息,{}內(nèi)為注釋):
AT
OK
AT+CMGL=2 {讀未發(fā)短信息}
+CMGL: 1,2,,24 {1表示信息個數(shù),2表示未發(fā)信息,24表示信息總?cè)萘縸
08 91 683108501505F0 11 00 0B 81 3106656930F1 0000A7 0B E8329BFD06DDDF723619
OK
下面分析這條信息:
08:短信息中心地址長度。
91:短信息中心號碼類型,91是TONNPI。TONNPI遵守InternationalE.164標(biāo)準(zhǔn),指在號碼前需加‘+'號;此外還可有其他數(shù)值,但91最常用。
683108501505F0:短信息號碼,是所使用的服務(wù)中心地址。由于位置上略有處理,實際號碼應(yīng)為:8613805515500(字母F意指長度減1),這是作者所在地GSM短信息中心的號碼。
11:文件頭字節(jié)(header byte,是一種bitmask)。這里11指正常地發(fā)送短信息。
00:信息類型。
0B:被叫號碼長度。
81:被叫號碼類型。
3106656930F1:被叫號碼,也經(jīng)過了移位處理,實際號碼為13605696031。
0000A7:短信息編碼類型GSM Default Alphabet,如為中文則是000010。
0B:短信息長度。
E8329BFD06DDDF723619:短信息內(nèi)容“Hello World!”。
短信息的編碼方法及編程實現(xiàn)
下面我們介紹純英文和純中文的信息編碼方法。通過測試我們發(fā)現(xiàn),每條發(fā)送的短信息前面部分均相同,只是被叫號碼和短信息內(nèi)容有變化。
1.英文編碼
參見表2,設(shè)短信息內(nèi)容為“Hello World!”。缺省的GSM 字符集為7位編碼,可以簡單地理解為ASCII碼(ASCII值小于80Hex,因此,Bit8被忽略),依次將下一7位編碼的后幾位逐次移至前面,形成新的8位編碼,參見表2箭頭指示。需要注意的是第9行,移位計數(shù)已達(dá)7位,則直接將本編碼前加0。GSM并非支持所有的ASCII字符顯示。
表2 英文編碼的實現(xiàn)過程
下面是實現(xiàn)英文編碼的部分Delphi 5代碼:
//英文格式編碼,s為String
function Encode1(var s:String):String;
var
i,j,len:Integer;
cur:Integer;
t:String;
begin
Result:=‘';
len:=Length(s);
//j 用于移位計數(shù)
i:=1;j:=0;
while i<=len do
begin
if i//數(shù)據(jù)變換
cur:=(ord(s[i]) shr j) or ((ord(s[i+1]) shl (7-j)) and $ff)
else
cur:=(ord(s[i]) shr j) and $7f;
FmtStr(t,‘%2.2X',[cur]);
Result:=Result+t;
inc(i);
//移位計數(shù)達(dá)到7位的特別處理
j:=(j+1) mod 7;if j=0 then inc(i);
end;
end;
2.中文編碼
參見表3,設(shè)短信息內(nèi)容為“中文短信息”。中文短信息的實現(xiàn)較簡單,只需將GB2312的中文編碼轉(zhuǎn)換為代碼頁為CP936的Unicode編碼即可。
表3 中文編碼的實現(xiàn)過程
通過Delphi的WideString類型轉(zhuǎn)換,可以巧妙地實現(xiàn)GB2312到Unicode的編碼轉(zhuǎn)換(注意代碼頁和操作系統(tǒng)相關(guān)聯(lián))。下面是實現(xiàn)中文編碼的部分Delphi 5代碼:
// 中文格式編碼,s為Unicode String
function Encode2(var s:WideString):String;
var
i,len:Integer;
cur:Integer;
t:String;
begin
Result:=‘';
len:=Length(s);
i:=1;
while i<=len do
begin
cur:=ord(s[i]);
//BCD轉(zhuǎn)換
FmtStr(t,‘%4.4X',[cur]);
Result:=Result+t;
inc(i);
end;
end;
小 結(jié)
以上介紹了PDU格式的短信息編碼。建議英文信息長度不超過140個字符,中文信息不要超過54個漢字。如果使用能夠支持文本方式的手機(jī)進(jìn)行發(fā)送,實現(xiàn)起來更簡單。如發(fā)送“Hello World!”,用如下的AT指令即可:
AT+CGMF=1AT+CGMS=“13650246680”,129
>Hello World!<^Z>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -