你的解码程序有问题。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FCountryCode: string;
function ParseAPDUMessage(const sPDUMsg: string; var sGSMCenter,
sMobile, sMsg,
sTimeStamp: string;
var iType: integer; var bFreeHand, bBackCall,
bFlashSMS: boolean): Boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
function StrToBoolean(const Value: string): boolean;
function PDUToString7Bit (v : string) : string;
function PDUToStringUCS2 (v : string) : string;
implementation
{$R *.dfm}
function StrToBoolean(const Value: string): boolean;
begin
Result := Value = '1';
end;
function PDUToString7Bit (v : string) : string;
var
I, InLen, OutLen, OutPos : Integer;
TempByte, PrevByte : Byte;
begin
{ Check for empty input }
if v = '' then Exit;
{ Init variables }
PrevByte := 0;
OutPos := 1;
{ Set length of output string }
InLen := Length(v);
Assert(InLen <= 140, 'Input string greater than 140 characters');
OutLen := (InLen * 8) div 7;
SetLength(Result, OutLen);
{ Encode output string }
for I := 1 to InLen do begin
TempByte := Byte(v);
TempByte := TempByte and not ($FF shl (7-((I-1) mod 7)));
TempByte := TempByte shl ((I-1) mod 7);
TempByte := TempByte or PrevByte;
Result[OutPos] := AnsiChar(TempByte);
Inc(OutPos);
{ Set PrevByte for next round (or directly put it to Result) }
PrevByte := Byte(v);
PrevByte := PrevByte shr (7-((I-1) mod 7));
if (I mod 7) = 0 then begin
Result[OutPos] := AnsiChar(PrevByte);
Inc(OutPos);
PrevByte := 0;
end;
end;
if Result[Length(Result)] = #0 then
Result := Copy(Result, 1, pred(Length(Result)));
end;
function PDUToStringUCS2 (v : string) : string;
var
i,len,j:Integer;
t:String;
begin
Result:='';
len:=Length(v);
i:=1;
while i<=len do begin
t:=Copy(v,i,4);
j:=StrToInt('$'+t);
t:=widechar(j);
Result:=Result+t;
i:=i+4;
end;
end;
function TForm1.ParseAPDUMessage(const sPDUMsg: string; var sGSMCenter,
sMobile, sMsg,
sTimeStamp: string;
var iType: integer; var bFreeHand, bBackCall,
bFlashSMS: boolean): Boolean;
var
sNext, sTmp, St, sCodec: string;
iNumLength, I, TempI: integer;
bHasUDHI, bIsStatusReport: boolean;
begin
try
sNext := sPDUMsg;
iNumLength := StrToInt(Copy(sNext, 0, 2));
I := 0;
//NumLength is length of center number, in octets
if iNumLength > 0 then
begin
// Next two digits is Type-of-Address octet
I := StrToInt(Copy(sNext, 3, 2));
// I is the Type-of-Address octet
case I of
91 : begin
end;
81 : begin
end;
end; // End Case
// NumLength = length of center phone number
sTmp := '';
I := 5;
while I < (iNumLength * 2 + 3) do
begin
if sNext = 'F' then
sTmp := sTmp + sNext[I+1]
else
sTmp := sTmp + sNext[I+1] + sNext;
I := I + 2;
end;
// TempStaID is the Center Address at this point
sGSMCenter := sTmp;
end
else
begin
sNext := Copy(sNext, 3, Length(sNext));
end;
// TempI = octet is First Octet of SMS-Deliver PDU
TempI := StrToInt(Copy(sNext, I, 2));
// Get next octet
sNext := Copy(sNext, I + 2, Length(sNext));
St := Copy(sNext, 0, 2);
bHasUDHI := (TempI and $40) = $40;
bBackCall := (TempI and $80) = $80;
bIsStatusReport := (TempI and $02) = $02;
if not bIsStatusReport then
begin
case TempI of
4 : begin // This PDU is a SMS delivery
end;
11: begin // Message ready to send
if St = '00' then begin
// The "00" lets the phone set the message reference number.
sNext := Copy(sNext, 3, Length(sNext));
St := Copy(sNext, 0, 2);
end;
end;
24: begin // Status report indication returned
end;
end; // End Case
//Address-Length. Length of the sender number (0B hex = 11 dec)
iNumLength := (StrToInt('$' + St));
// Next two digits is Type-of-Address octet
I := StrToInt('$' + Copy(sNext, 3, 2));
case I of
133 : begin
// 85 in Hex = Voice mail ?
end;
145 : begin
// 91 in Hex
end;
129 : begin
// 81 in Hex
end;
200 : begin
// C8 in Hex
end;
end; // End Case
// NumLength = Length of phone number
sTmp := '';
if Odd(iNumLength) then
iNumLength := iNumLength + 1;
// Change NumLength to Octets
iNumLength := iNumLength Div 2;
I := 5;
while I < (iNumLength * 2 + 5) do begin
if sNext = 'F' then
sTmp := sTmp + sNext[I+1]
else
sTmp := sTmp + sNext[I+1] + sNext;
I := I + 2;
end;
// TempStaID is the StationID at this point
if Copy(sTmp, 1, Length(FCountryCode)) = FCountryCode then //remove the countrycode
sTmp := Copy(sTmp, Length(FCountryCode) + 1, Length(sTmp));
sMobile := sTmp;
// Protocol identifier of "00" and Data coding scheme of "00"
// are the 2 octets or the 4 added to I, below
sTmp := Copy(sNext, I, 2);
bBackCall := sTmp = '5F';
sCodec := Copy(sNext, I + 2, 2);
I := I + 4; // start of time stamp
St := '';
if sNext = 'A' then begin
// No time stamp - not sent yet
TempI := I + 2;
end else begin
St := sNext[I+1] + sNext + '/' + // Year
sNext[I+3] + sNext[I+2] + '/' + // Month
sNext[I+5] + sNext[I+4] + ',' + // Day
sNext[I+7] + sNext[I+6] + ':' + // Hours
sNext[I+9] + sNext[I+8] + ':' + // Minutes
sNext[I+11] + sNext[I+10] + '+' + // Seconds
sNext[I+13] + sNext[I+12]; // Time Zone
// 14 is length of time stamp - Keeping track where we are in TempS
TempI := I + 14;
sTimeStamp := St;
end;
// Get next octet
St := sNext[TempI] + sNext[TempI + 1];
// MessageLength
// iMessageLength := StrToInt('$' + St);
// U is the message
sNext := Copy(sNext, TempI + 2, Length(sNext));
// NumLength is the length of the message
iNumLength := Length(sNext);
sTmp := Copy(sCodec, 1, 1);
bFreeHand := StrToBoolean(sTmp);
if Copy(sCodec, 2, 1) = '0' then
begin
iType := 0;
// Change message to string form
// Set pointer to start of message
if Copy(sNext, 1, 4) = '0001' then
begin
bFlashSMS := True;
sNext := Copy(sNext, 5, iNumLength);
Dec(iNumLength, 4);
end;
if bHasUDHI then
begin
sCodec := Char(StrToInt('$' + Copy(sNext, 13, 2)) shr 1);
sNext := Copy(sNext, 15, iNumLength);
Dec(iNumLength, 14);
end;
I := 1;
sTmp := '';
while I < iNumLength do begin
St := '$' + sNext + sNext[I+1];
TempI := StrToInt(St);
sTmp := sTmp + Char(TempI);
I := I + 2;
end;
sNext := PDUToString7Bit(sTmp);
if bHasUDHI then
sNext := sCodec + sNext;
end
else if Copy(sCodec, 2, 1) = '8' then //汉字
begin
iType := 1;
if Copy(sNext, 1, 4) = '0001' then
begin
bFlashSMS := True;
sNext := Copy(sNext, 5, iNumLength);
Dec(iNumLength, 4);
end;
if bHasUDHI then
begin
sNext := Copy(sNext, 13, iNumLength);
Dec(iNumLength, 12);
end;
sNext := PDUToStringUCS2(sNext);
end
else if sCodec = '15' then //二进制 60029339
begin
iType := 2;
if bHasUDHI then
begin
sNext := Copy(sNext, 13, iNumLength);
Dec(iNumLength, 12);
end;
end;
// if iMessageLength = Length(sNext) then
// Store message
sMsg := sNext;
end
else
begin
Result := True;
end;
Result := True;
except
Result := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
sGSMCenter, sMobile, sMsg, sTimeStamp: string;
iType: integer;
bFreeHand, bBackCall, bFlashSMS: boolean;
begin
FCountryCode := Edit1.Text;
ParseAPDUMessage(Memo1.Text, sGSMCenter, sMobile, sMsg, sTimeStamp, iType, bFreeHand, bBackCall, bFlashSMS);
Memo2.Lines.Add(sGSMCenter);
Memo2.Lines.Add(sMobile);
Memo2.Lines.Add(sMsg);
Memo2.Lines.Add(sTimeStamp);
end;
end.