www.pudn.com > at.rar > PunFun.pas


unit PunFun; 
 
interface 
 
  //把十六进制字符串转换为二进制字符串 
  function HexToBin(HexNr : string): string; 
  //转换一个十六进制字符为整数 
  function HexCharToInt(HexToken : char):Integer; 
  //把十六进制字符串转换为二进制字符串 
  function HexCharToBin(HexToken : char): string; 
  //指数函数 
  function pow(base, power: integer): integer; 
  //把二进制字符串转换为整数 
  function BinStrToInt(BinStr : string) : integer; 
  //解码一个7-bit SMS(GSM 03.38)为ASCII码 
  function DecodeSMS7Bit(PDU : string):string; 
  //返转一个字符串 
  function ReverseStr(SourceStr : string) : string; 
  //把字符串中前后两个字符调换位置 
  function ChangePlaceS(SourceStr: string) : string; 
  //转换一个十六进制字符串为整数 
  function HexStrToInt(SourceStr: string) : Integer; 
  //求出一个宽字符的ASCII码值 
  function WideCharToASC(SourceWideChar: WideChar): Integer; 
  //此函数是用来求出字符串SubStr在字符串S从StartPos以后的位置 
  function Postion(Substr,S: string; StartPos: Integer): Integer; 
  //此函数是用来判断字符串是否为十六进制字符串 
  function IfHex(S: string): Boolean; 
  //此函数是用来判断字符串SubStr在字符串S中出现的次数 
  function CountStr(SubStr,S: string): integer; 
  //此函数是用来把从GSM模块中读到的短信内容翻译出来 
  function SMSDecode(SourCode: string; var HandNum,SmsInfo,SendTime: string): Smallint; 
  //此函数是用来把电话号码和短消息内容转换成相应的16进制代码 
  function SMChangHex(HandNum: string; SendInfo: string):string; 
 
implementation 
 
uses sysutils, strutils; 
 
///////////////////////////////////////////////////////////// 
//说  明:此函数是用来把电话号码和短消息内容转换成相应的16进制代码 
//函数名:SMChangHex 
//参  数:1、HandNum:  手机号码 
//        2、SendInfo:  短信内容 
//返回值:string  转换后的16进制字符串 
//作  者:卞伟    2003年1月 
///////////////////////////////////////////////////////////// 
function SMChangHex(HandNum: string; SendInfo: string):string; 
var 
  I: integer; 
  Temp: string; 
  strUcode: UCS4String; 
begin 
  Result:= ''; 
  //--------------------------------------------------------- 
  //转换手机号码 
  //--------------------------------------------------------- 
  if LeftBStr(HandNum,3) = '+86' then 
    HandNum:= RightBStr(HandNum,Length(HandNum) -1) + 'F' 
  else if LeftBStr(HandNum,2) = '86' then 
    HandNum:= HandNum + 'F' 
  else 
    HandNum:= '86' + HandNum + 'F'; 
 
  Temp:= ''; 
  for I:= 1 to Length(HandNum) div 2 do 
  begin 
    Temp:= Temp + MidBStr(HandNum,I * 2,1) + MidBStr(HandNum,I * 2 - 1,1); 
  end; 
  HandNum:= Temp; 
 
  //---------------------------------------------------------- 
  //转换短信息内容为unicode编码 
  //---------------------------------------------------------- 
  strUcode:= WideStringToUCS4String(SendInfo); 
  Temp:= ''; 
  for I:= 1 to Length(WideString(SendInfo)) do 
  begin 
    Temp:= Temp + IntToHex(strUcode[I - 1],4); 
  end; 
  SendInfo:= Temp; 
 
  //放头标记和字符总长数及编码类型 
  //Temp:= '0021010D91' + HandNum + '0008' + IntToHex(Length(SendInfo) div 2,2) + SendInfo; 
  Result:= '0021010D91' + HandNum + '0008' + IntToHex(Length(SendInfo) div 2,2) + SendInfo; 
//  Result:= Temp; 
//  Result:= 'AT+CMGS=' + IntToStr(Length(Temp) div 2 - 1) + Chr(13);// + Temp + Chr(26); 
end; 
 
////////////////////////////////////////////////////////////////// 
//描  述:此函数是用来把从GSM模块中读到的短信内容翻译出来 
//函数名:SMSDecode 
//参  数:1、SourCode     源字符串 
//        2、PCenterNum   解码后的短信中心号码 
//        3、HandNum      发送方手机号码 
//        4、SmsInfo      接收到的短信内容 
//        5、SendTime     发送时间 
//返  回:Smallint 
//        0: 成功 
//        -1:失败 
//作  者:卞伟  2002.12 
//////////////////////////////////////////////////////////////// 
function SMSDecode(SourCode: string; var HandNum,SmsInfo,SendTime: string): Smallint; 
var 
  TempS: string; 
  TempI: Integer; 
  CentreNum: string; //短信中心号码 
  TP_DCS:    string;  //数据编码方式 
  I:         Integer; 
begin 
  result:= 0; 
  SourCode:= TrimRight(SourCode);  //删除结尾部分的控制字符及空格字符 
  SourCode:= TrimLeft(SourCode);  //删除开头部分的控制字符及空格字符 
  TempI:= Pos(#13 + #10,SourCode); 
  TempS:= LeftStr(SourCode,TempI - 1); //取得引导部分 
  SourCode:= RightStr(SourCode,Length(SourCode) - TempI -1); //取得剩余的部分 
 
  TempS:= TrimRight(TempS);     //删除结尾部分的控制字符及空格字符 
  SourCode:= TrimLeft(SourCode);  //删除开头部分的控制字符及空格字符 
 
  if (Length(TempS) > 9) and (Pos('"REC ',TempS) > 0) then //标示是在发送模式为1(即TEXT)时收到的信息 
  begin 
    Delete(TempS,1,Pos('","',TempS) + 2); 
    HandNum:= MidBStr(TempS,2,Pos('",',TempS) - 2); 
    Delete(TempS,1,Pos('",,"',TempS) + 3); 
    SendTime:= LeftStr(TempS,Pos('"',TempS) -1); 
    SendTime:= '20' + LeftStr(TempS,2) + '-' + MidBStr(TempS,4,2) + '-' + MidBStr(TempS,7,2) + ' ' + MidBStr(TempS,10,8); 
    Delete(Temps,1,Pos(#13 + #10,TempS) + 1); 
 
    TempI:= Pos(#13 + #10,SourCode); 
    if TempI > 0 then 
      SmsInfo:= LeftStr(SourCode,TempI -1) 
    else 
      SmsInfo:= SourCode; 
 
    if (IfHex(SmsInfo)) and (Length(SmsInfo) mod 4 = 0) then 
    //为十六进制编码 
    begin 
     //标示二个字节代表一个字符号 
      TempS:= ''; 
      for I:= 1 to Length(SmsInfo) div 4 do 
      begin 
        SourCode:= MidBStr(SmsInfo, I * 4 -3,4); 
        TempS:= TempS + widechar(HexStrToInt(SourCode)); 
      end; 
      SmsInfo:= TempS; 
    end; 
  end 
  else //标示是在发送模式为0(即PDU)时收到的信息 
  begin 
    //求出短信中心号码 
    TempI:= HexStrToInt(MidBStr(SourCode,1,2)) * 2; 
    CentreNum:= MidBStr(SourCode,5,TempI - 2); 
    CentreNum:= LeftStr(ChangePlaceS(CentreNum),Length(CentreNum) -1); 
 
    //求出不包括短信中心号码的字符串 
    SourCode:= RightStr(SourCode,Length(SourCode) - 2 - TempI); 
    //删除掉SMS_DELIVER的第一个8位 
    SourCode:= RightStr(SourCode,LengtH(SourCode) - 2); 
    //-------------------------------- 
    //求出发送方手机号码 
    //--------------------------------- 
    //求出手机号码的长度 
    TempI:= HexStrToInt(MidBStr(SourCode,1,2)); 
    if (TempI mod 2) > 0 then 
    begin 
      //标志手机号码长度为奇数 
      TempI:= TempI + 1; 
      //求出手机号码 
      TempS:= MidBStr(SourCode,5,TempI); 
      //转换位置 
      TempS:= ChangePlaceS(TempS); 
      //去掉后面的“F” 
      HandNum:= LeftStr(TempS,TempI -1); 
    end 
    else 
    begin 
      //求出手机号码 
      TempS:= MidBStr(SourCode,5,TempI); 
      //转换位置 
      TempS:= ChangePlaceS(TempS); 
    end; 
 
    //求出剩余的内容 
    SourCode:= RightStr(SourCode,Length(SourCode) - TempI - 4); 
    //求出数据的编码方式 
    TP_DCS:= MidBStr(SourCode, 3, 2); 
 
    //求出不包括数据编码方式的内容 
    SourCode:= RightStr(SourCode,Length(SourCode) - 4); 
 
    //求出日期及时间。格式为:2002-10-21 11:30:40.140 
    TempS:= ChangePlaceS(LeftStr(SourCode,12)); 
    SendTime:= '20' + LeftStr(TempS,2);  //年 
    SendTime:= SendTime + '-' + MidBStr(TempS,3,2); //月 
    SendTime:= SendTime + '-' + MidBStr(TempS,5,2); //日 
    SendTime:= SendTime + ' ' + MidBStr(TempS,7,2); //时 
    SendTime:= SendTime + ':' + MidBStr(TempS,9,2); //分 
    SendTime:= SendTime + ':' + MidBStr(TempS,11,2); //秒 
 
    //求出接收到的字符串的长度 
    TempI:= HexStrToInt(MidBStr(SourCode,15,2)) * 2; 
 
    //求出不包括日期时间及长度的字符串 
    SourCode:= RightStr(SourCode,Length(Sourcode) - 16); 
 
    //求出短信内容 
    SmsInfo:= LeftStr(SourCode,TempI); 
    //解释短信内容 
    if TP_DCS = '00' then 
    begin 
    //7Bit代表一个字符 
      SmsInfo:= DecodeSMS7Bit(SmsInfo); 
    end 
    else if TP_DCS = '08' then 
    begin 
    //标示二个字节代表一个字符号 
      TempS:= ''; 
      for I:= 1 to Length(SmsInfo) div 4 do 
      begin 
        SourCode:= MidBStr(SmsInfo, I * 4 -3,4); 
        TempS:= TempS + widechar(HexStrToInt(SourCode)); 
      end; 
      SmsInfo:= TempS; 
    end; 
  end; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:此函数是用来判断字符串SubStr在字符串S中出现的次数 
//函数名: CountStr 
//参  数:1、SubStr 
//        2、S 
//返  回:Integer 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function CountStr(SubStr,S: string): integer; 
var 
  Count: integer; 
  Temp: Integer; 
begin 
  Count:= 1; 
  Result:= 0; 
  while True do 
  begin 
    Temp:= Postion(SubStr,S,Count); 
    if Temp > 0 then 
    begin 
      Count:= Count + Length(SubStr) + Temp; 
      Result:= Result + 1; 
    end 
    else 
      Exit; 
  end; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:此函数是用来判断字符串是否为十六进制字符串 
//函数名: IfHex 
//参  数:S       :源字符串 
//返  回:Boolean 
//        True: 是 
//        False: 否 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function IfHex(S: string): Boolean; 
var 
  I: Integer; 
begin 
  Result:= True; 
  for I:= 1 to Length(S) do 
  begin 
    Case S[I] of 
      '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F': begin end; 
    else begin 
           Result:= False; 
           Exit; 
         end; 
    end; 
  end 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:此函数是用来求出字符串SubStr在字符串S从StartPos以后的位置 
//函数名: Postion 
//参  数:1、Substr  :需要查看的字符串 
//        2、S       :源字符串 
//        3、StartPos:开始位置 
//返  回:integer      整数 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function Postion(Substr,S: string; StartPos: Integer): Integer; 
begin 
  Delete(S,1,StartPos - 1); 
  Result:= Pos(SubStr,S); 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:求出一个宽字符的ASCII码值 
//函数名: WideCharToASC 
//参  数:1、SourceWideChar   宽字符 
//返  回:integer      整数 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function WideCharToASC(SourceWideChar: WideChar): Integer; 
begin 
  Result:= Integer(SourceWideChar); 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:转换一个十六进制字符串为整数 
//函数名: HexStrToInt 
//参  数:1、SourceStr   十六进制字符串 
//返  回:integer      整数 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function HexStrToInt(SourceStr : string):Integer; 
var 
  I: Integer; 
begin 
  Result:= 0; 
  for I:= 1 to Length(SourceStr) do 
  begin 
    Result:= Result + HexCharToInt(SourceStr[I]) * (pow(16,Length(SourceStr) - I)); 
  end; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:转换一个十六进制字符为整数 
//函数名: HexCharToInt 
//参  数:1、HexToken   十六进制字符 
//返  回:integer      整数 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function HexCharToInt(HexToken : char):Integer; 
begin 
  {if HexToken>#97 then HexToken:=Chr(Ord(HexToken)-32); 
  { use lowercase aswell } 
 
  Result:=0; 
 
  if (HexToken>#47) and (HexToken<#58) then       { chars 0....9 } 
     Result:=Ord(HexToken)-48 
  else if (HexToken>#64) and (HexToken<#71) then  { chars A....F } 
     Result:=Ord(HexToken)-65 + 10; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:把十六进制字符转换为二进制字符串 
//函数名: HexCharToBin 
//参  数:1、HexToken   十六进制字符 
//返  回:字符串      二进制字符串 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function HexCharToBin(HexToken : char): string; 
var 
  DivLeft : integer; 
begin 
    DivLeft:=HexCharToInt(HexToken);   { first HEX->BIN } 
    Result:=''; 
                                       { Use reverse dividing } 
    repeat                             { Trick; divide by 2 } 
      if odd(DivLeft) then             { result = odd ? then bit = 1 } 
        Result:='1'+Result             { result = even ? then bit = 0 } 
      else 
        Result:='0'+Result; 
 
      DivLeft:=DivLeft div 2;       { keep dividing till 0 left and length = 4 } 
    until (DivLeft=0) and (length(Result)=4);      { 1 token = nibble = 4 bits } 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:把十六进制字符串转换为二进制字符串 
//函数名: HexToBin 
//参  数:1、HexNr   十六进制字符串 
//返  回:字符串      二进制字符串 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function HexToBin(HexNr : string): string; 
{ only stringsize is limit of binnr } 
var 
  Counter : integer; 
begin 
  Result:=''; 
 
  for Counter:=1 to length(HexNr) do 
    Result:=Result+HexCharToBin(HexNr[Counter]); 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:指数函数 
//函数名: pow 
//参  数: 
//        1、base : INTEGER 
//        2、power:INTEGER 
//返  回:INTEGER 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function pow(base, power: integer): integer; 
var 
  counter : integer; 
begin 
  Result:=1; 
 
  for counter:=1 to power do 
    Result:=Result*base; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:把二进制字符串转换为整数 
//函数名: BinStrToInt 
//参  数: 
//        1、BinStr : 二进制字符串 
//返  回:INTEGER 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function BinStrToInt(BinStr : string) : integer; 
var 
  counter : integer; 
begin 
  if length(BinStr)>16 then 
    raise ERangeError.Create(#13+BinStr+#13+ 
            'is not within the valid range of a 16 bit binary.'+#13); 
 
  Result:=0; 
 
  for counter:=1 to length(BinStr) do 
      if BinStr[Counter]='1' then 
        Result:=Result+pow(2,length(BinStr)-counter); 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:解码一个7-bit SMS(GSM 03.38)为ASCII码 
//函数名: DecodeSMS7Bit 
//参  数: 
//        1、PDU : 7-bit编码字符串 
//返  回:string 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function DecodeSMS7Bit(PDU : string):string; 
var 
  OctetStr : string; 
  OctetBin : string; 
  Charbin  : string; 
  PrevOctet: string; 
  Counter  : integer; 
  Counter2 : integer; 
begin 
  PrevOctet:=''; 
  Result:=''; 
 
  for Counter:=1 to length(PDU) do 
    begin 
      if length(PrevOctet)>=7 then     { if 7 Bit overflow on previous } 
        begin 
          if BinStrToInt(PrevOctet)<>0 then 
            Result:=Result+Chr(BinStrToInt(PrevOctet)) 
          else Result:=Result+' '; 
 
          PrevOctet:=''; 
        end; 
 
      if Odd(Counter) then            { only take two nibbles at a time } 
        begin 
          OctetStr:=Copy(PDU,Counter,2); 
          OctetBin:=HexToBin(OctetStr); 
 
          Charbin:=''; 
          for Counter2:=1 to length(PrevOctet) do 
            Charbin:=Charbin+PrevOctet[Counter2]; 
 
          for Counter2:=1 to 7-length(PrevOctet) do 
            Charbin:=OctetBin[8-Counter2+1]+Charbin; 
 
          if BinStrToInt(Charbin)<>0 then Result:=Result+Chr(BinStrToInt(CharBin)) 
            else Result:=Result+' '; 
 
          PrevOctet:=Copy(OctetBin,1,length(PrevOctet)+1); 
        end; 
    end; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:返转一个字符串 
//函数名: ReverseStr 
//参  数: 
//        1、SourceStr : 字符串 
//返  回:string 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function ReverseStr(SourceStr : string) : string; 
var 
  Counter : integer; 
begin 
  Result:=''; 
 
  for Counter:=1 to length(SourceStr) do 
    Result:=SourceStr[Counter]+Result; 
end; 
 
////////////////////////////////////////////////////////////////// 
//目  的:把字符串中前后两个字符调换位置 
//函数名: ChangePlaceS 
//参  数: 
//        1、SourceStr : 字符串 
//返  回:string 
//作  者:卞伟  2002.12 
////////////////////////////////////////////////////////////////// 
function ChangePlaceS(SourceStr: string) : string; 
var 
  I: Integer; 
begin 
  Result:= ''; 
 
  for I:= 1 to Length(SourceStr) div 2 do 
    Result:= Result + SourceStr[I * 2] + SourceStr[I * 2 -1]; 
 
  if (Length(SourceStr) mod 2) > 0 then 
    Result:= Result + SourceStr[Length(SourceStr)]; 
end; 
 
end.