📄 smscodec.pas
字号:
{ --------------------------------------------------------- }
{ Purposes : }
{ 1. Convert ASCII to 7-bit PDU }
{ 2. Convert 7-bit, 8-bit and 16-bit PDU to ASCII }
{ 3. Decode/Parsing the hexadecimal (PDU) of SMS message }
{ 4. Encode ASCII characters to be sent as SMS ready string }
{ }
{ --------------------------------------------------------- }
{ Coder : Daniel Eka Nugraha }
{ URL : http://www.averagecoder.com/ }
{ Email : pinoez@yahoo.com }
{ --------------------------------------------------------- }
{ This is not a perfect one, so Use it at your own risk ! }
{ --------------------------------------------------------- }
unit SMSCODEC;
interface
uses
Windows, Messages, SysUtils, Classes, StrUtils, Math, Dialogs;
type
TSMSCODEC = class(TComponent)
private
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Binerkan(Angka: integer): string;
function Bin2Long(StrBiner: string): integer;
function PDU7BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string;
function PDU8BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string;
function PDU16BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string;
function ASCII2PDU7BIT(StrASCII: string): string;
function DecodeSMS(StrSMS : string) : TStringList;
function EncodeSMS(StrTujuan, StrPesan: string): string;
published
{ Published declarations }
end;
procedure Register;
implementation
var Nono: integer;
EQ7BIT2ASCII : array [0..127] of integer; // Table persamaan 7-bit ke ASCII
EQASCII27BIT : array [0..255] of integer; // Table persamaan ASCII ke 7-bit
procedure Register;
begin
RegisterComponents('averagecoder', [TSMSCODEC]);
end;
constructor TSMSCODEC.Create(AOwner: TComponent);
var i : integer;
begin
inherited Create(AOwner);
// This is the transition table from 7-bit to ASCII
Nono := -1;
EQ7BIT2ASCII[0] := 64;
EQ7BIT2ASCII[1] := 163;
EQ7BIT2ASCII[2] := 36;
EQ7BIT2ASCII[3] := 165;
EQ7BIT2ASCII[4] := 232;
EQ7BIT2ASCII[5] := 223;
EQ7BIT2ASCII[6] := 249;
EQ7BIT2ASCII[7] := 236;
EQ7BIT2ASCII[8] := 242;
EQ7BIT2ASCII[9] := 199;
EQ7BIT2ASCII[10] := 10;
EQ7BIT2ASCII[11] := 216;
EQ7BIT2ASCII[12] := 248;
EQ7BIT2ASCII[13] := 13;
EQ7BIT2ASCII[14] := 197;
EQ7BIT2ASCII[15] := 229;
EQ7BIT2ASCII[16] := Nono;
EQ7BIT2ASCII[17] := 95;
EQ7BIT2ASCII[18] := Nono;
EQ7BIT2ASCII[19] := Nono;
EQ7BIT2ASCII[20] := Nono;
EQ7BIT2ASCII[21] := Nono;
EQ7BIT2ASCII[22] := Nono;
EQ7BIT2ASCII[23] := Nono;
EQ7BIT2ASCII[24] := Nono;
EQ7BIT2ASCII[25] := Nono;
EQ7BIT2ASCII[26] := Nono;
EQ7BIT2ASCII[27] := Nono;
EQ7BIT2ASCII[28] := 198;
EQ7BIT2ASCII[29] := 230;
EQ7BIT2ASCII[30] := 223;
EQ7BIT2ASCII[31] := 201;
EQ7BIT2ASCII[32] := 32;
EQ7BIT2ASCII[33] := 33;
EQ7BIT2ASCII[34] := 34;
EQ7BIT2ASCII[35] := 35;
EQ7BIT2ASCII[36] := 164;
EQ7BIT2ASCII[37] := 37;
EQ7BIT2ASCII[38] := 38;
EQ7BIT2ASCII[39] := 39;
EQ7BIT2ASCII[40] := 40;
EQ7BIT2ASCII[41] := 41;
EQ7BIT2ASCII[42] := 42;
EQ7BIT2ASCII[43] := 43;
EQ7BIT2ASCII[44] := 44;
EQ7BIT2ASCII[45] := 45;
EQ7BIT2ASCII[46] := 46;
EQ7BIT2ASCII[47] := 47;
EQ7BIT2ASCII[48] := 48;
EQ7BIT2ASCII[49] := 49;
EQ7BIT2ASCII[50] := 50;
EQ7BIT2ASCII[51] := 51;
EQ7BIT2ASCII[52] := 52;
EQ7BIT2ASCII[53] := 53;
EQ7BIT2ASCII[54] := 54;
EQ7BIT2ASCII[55] := 55;
EQ7BIT2ASCII[56] := 56;
EQ7BIT2ASCII[57] := 57;
EQ7BIT2ASCII[58] := 58;
EQ7BIT2ASCII[59] := 59;
EQ7BIT2ASCII[60] := 60;
EQ7BIT2ASCII[61] := 61;
EQ7BIT2ASCII[62] := 62;
EQ7BIT2ASCII[63] := 63;
EQ7BIT2ASCII[64] := 161;
EQ7BIT2ASCII[65] := 65;
EQ7BIT2ASCII[66] := 66;
EQ7BIT2ASCII[67] := 67;
EQ7BIT2ASCII[68] := 68;
EQ7BIT2ASCII[69] := 69;
EQ7BIT2ASCII[70] := 70;
EQ7BIT2ASCII[71] := 71;
EQ7BIT2ASCII[72] := 72;
EQ7BIT2ASCII[73] := 73;
EQ7BIT2ASCII[74] := 74;
EQ7BIT2ASCII[75] := 75;
EQ7BIT2ASCII[76] := 76;
EQ7BIT2ASCII[77] := 77;
EQ7BIT2ASCII[78] := 78;
EQ7BIT2ASCII[79] := 79;
EQ7BIT2ASCII[80] := 80;
EQ7BIT2ASCII[81] := 81;
EQ7BIT2ASCII[82] := 82;
EQ7BIT2ASCII[83] := 83;
EQ7BIT2ASCII[84] := 84;
EQ7BIT2ASCII[85] := 85;
EQ7BIT2ASCII[86] := 86;
EQ7BIT2ASCII[87] := 87;
EQ7BIT2ASCII[88] := 88;
EQ7BIT2ASCII[89] := 89;
EQ7BIT2ASCII[90] := 90;
EQ7BIT2ASCII[91] := 196;
EQ7BIT2ASCII[92] := 204;
EQ7BIT2ASCII[93] := 209;
EQ7BIT2ASCII[94] := 220;
EQ7BIT2ASCII[95] := 167;
EQ7BIT2ASCII[96] := 191;
EQ7BIT2ASCII[97] := 97;
EQ7BIT2ASCII[98] := 98;
EQ7BIT2ASCII[99] := 99;
EQ7BIT2ASCII[100] := 100;
EQ7BIT2ASCII[101] := 101;
EQ7BIT2ASCII[102] := 102;
EQ7BIT2ASCII[103] := 103;
EQ7BIT2ASCII[104] := 104;
EQ7BIT2ASCII[105] := 105;
EQ7BIT2ASCII[106] := 106;
EQ7BIT2ASCII[107] := 107;
EQ7BIT2ASCII[108] := 108;
EQ7BIT2ASCII[109] := 109;
EQ7BIT2ASCII[110] := 110;
EQ7BIT2ASCII[111] := 111;
EQ7BIT2ASCII[112] := 112;
EQ7BIT2ASCII[113] := 113;
EQ7BIT2ASCII[114] := 114;
EQ7BIT2ASCII[115] := 115;
EQ7BIT2ASCII[116] := 116;
EQ7BIT2ASCII[117] := 117;
EQ7BIT2ASCII[118] := 118;
EQ7BIT2ASCII[119] := 119;
EQ7BIT2ASCII[120] := 120;
EQ7BIT2ASCII[121] := 121;
EQ7BIT2ASCII[122] := 122;
EQ7BIT2ASCII[123] := 228;
EQ7BIT2ASCII[124] := 246;
EQ7BIT2ASCII[125] := 241;
EQ7BIT2ASCII[126] := 252;
EQ7BIT2ASCII[127] := 224;
// This is the transition table from ASCII to 7-BIT; index reversing :)
for i := 0 to High(EQ7BIT2ASCII) do
begin
if EQ7BIT2ASCII[i] <> Nono then
EQASCII27BIT[EQ7BIT2ASCII[i]] := i;
end;
end; { TSMSCODEC.Create }
destructor TSMSCODEC.Destroy;
begin
inherited Destroy;
end; { TSMSCODEC.Destroy }
{
--------------------------------------------------------------------------------
function Binerkan
-> Convert integer to binary
-> parameters:
Angka: integer; -> the integer value
-> Return value: string of 1 and 0 (nothing genius at all :D)
--------------------------------------------------------------------------------
}
function TSMSCODEC.Binerkan(Angka : integer): string;
var i : Integer;
hasil : array [0..7] of Integer;
SISA : array [0..7] of Integer;
StrHasil : string;
begin
result := '';
if angka > 1 Then
begin
i := 1;
repeat
hasil[i] := Trunc(angka / 2);
SISA[i] := angka mod 2;
angka := hasil[i];
i := i + 1;
StrHasil := IntToStr(SISA[i - 1]) + StrHasil;
until hasil[i - 1] < 2;
StrHasil := IntToStr(hasil[i - 1]) + StrHasil;
end
else if angka = 1 then
StrHasil := '00000001'
else if angka = 0 Then
StrHasil := '00000000';
for i := 1 to (8 - Length(StrHasil)) do
StrHasil := '0' + StrHasil;
result := StrHasil;
end; { TSMSCODEC.Binerkan }
{
--------------------------------------------------------------------------------
function Bin2Long
-> Convert binaty string to integer
-> Parameter:
StrBiner: string; -> the binary string;
-> Return value: integer;
--------------------------------------------------------------------------------
}
function TSMSCODEC.Bin2Long(StrBiner : string): integer;
var i, x : integer;
begin
x := 0;
for i := 1 to Length(StrBiner) do
begin
x := x + StrToInt(Copy(StrBiner, i, 1)) * Trunc(Power(2,(Length(StrBiner) - i)));
end;
result := x;
end; { TSMSCODEC.Bin2Long }
{
--------------------------------------------------------------------------------
function PDU7BIT2ASCII
-> Convert PDU (string 7-bit PDU) to ASCII
-> Parameter:
StrPDU: string -> the PDUString
PanjangUDH: integer; -> the length of the UDH
PanjangData: integer; -> the length of the data
-> return value: ASCII string
--------------------------------------------------------------------------------
}
function TSMSCODEC.PDU7BIT2ASCII(StrPDU : string; PanjangUDH, PanjangData: integer) : string;
var i,j,x,z : integer;
y, StrASCII : string;
ArrPDU : array of string;
Arr7Bit : array of string;
ArrASCII : array of string;
begin
j := 1;
z := 0;
// 2 PDU chars represent 1 ASCII chars, so the length of the
// ASCII chars sequence is 1/2 of the string PDU length
SetLength(ArrPDU,Length(StrPDU) div 2);
// Load each pair of PDU string to the appropriate index of ArrPDU
while j < Length(StrPDU) do
begin
ArrPDU[z] := '$' + Copy(StrPDU,j,2); // '$' + string = hexadecimal
j := j + 2;
Inc(z);
end;
// Convert each ArrPDU item to binary for decoding
for i := 0 to High(ArrPDU) do
begin
y := ArrPDU[i];
ArrPDU[i] := '';
ArrPDU[i] := Binerkan(StrToInt(y));
end;
x := 0;
SetLength(Arr7BIT,x+1);
// The core process - the bit mutation
for i := 0 to High(ArrPDU) do
begin
if i mod 7 = 0 then
begin
Arr7BIT[x] := RightStr(ArrPDU[i],7);
end
else
begin
if i mod 7 = 6 then
begin
Arr7BIT[x] := RightStr(ArrPDU[i],1) + LeftStr(ArrPDU[i-1],6);
x := x + 1;
SetLength(Arr7BIT,x+1);
Arr7BIT[x] := LeftStr(ArrPDU[i],7);
end
else
Arr7BIT[x] := RightStr(ArrPDU[i],Length(ArrPDU[i])-(i mod 7)-1) + LeftStr(ArrPDU[i-1],i mod 7);
end;
x := x + 1;
SetLength(Arr7BIT,x+1);
end; { for }
j := 0;
while j <= High(Arr7BIT) do
begin
SetLength(ArrASCII,Length(ArrASCII)+1);
if Bin2Long(Arr7BIT[j]) = 27 then
begin
inc(j);
case Bin2Long(Arr7BIT[j]) of
10 : ArrASCII[High(ArrASCII)] := Chr(12);
20 : ArrASCII[High(ArrASCII)] := Chr(94);
40 : ArrASCII[High(ArrASCII)] := Chr(123);
41 : ArrASCII[High(ArrASCII)] := Chr(125);
47 : ArrASCII[High(ArrASCII)] := Chr(92);
60 : ArrASCII[High(ArrASCII)] := Chr(91);
61 : ArrASCII[High(ArrASCII)] := Chr(126);
62 : ArrASCII[High(ArrASCII)] := Chr(93);
64 : ArrASCII[High(ArrASCII)] := Chr(124);
else
ArrASCII[High(ArrASCII)] := Chr(0);
end;
end
else
begin
ArrASCII[High(ArrASCII)] := Chr(EQ7BIT2ASCII[Bin2Long(Arr7BIT[j])]);
end;
Inc(j);
end; { while }
SetLength(ArrASCII,PanjangData);
for i := 0 to High(ArrASCII) do
StrASCII := StrASCII + (ArrASCII[i]);
ArrPDU := nil; Arr7Bit := nil; ArrASCII := nil;
// if no UDH, ignore the octet info of UDH length,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -