前言:
現在很多STMP服務器在發送郵件時均需重新認證一遍,而Delphi的TNMSMTP控件對它沒有很“可視化”的支持,使很多人在開發過程中大打問號。
由於前段時間在做《CSDN查詢助手》的時候,使用的也是需認證的服務器(163.com)。從其它地方摘取了部分代碼得以解決,現在此發布與大家共享。
實現:
1、在NMSMTP的OnConnect事件中添加代碼:
var strUserName, strPassword: String;
begin
strUserName := EncodeString(CoolSlob);//CoolSlob是服務器的帳號
strPassword := EncodeString(Password);//Password是密碼
{進行認證,輸入編碼後的用戶名、密碼}
nmsmtp1.Transaction(EHLO) ;
nmsmtp1.Transaction(AUTH LOGIN);
nmsmtp1.Transaction(strUserName);
nmsmtp1.Transaction(strPassword);
StatusBar1.SimpleText := 連接成功;
end;
2、EncodeString函數實現過程:
{對參數Decoded字符串進行Base64編碼,返回編碼後的字符串}
function EncodeString(Decoded:string):String;
var
mmTemp,mmDecoded:TMemoryStream;
strTemp:TStrings;
begin
mmTemp := TMemoryStream.Create;
mmDecoded:=TMemoryStream.Create;
strTemp:=TStringList.Create;
strTemp.Add(Decoded);
strTemp.SaveToStream(mmTemp);
mmTemp.Position := 0;
{剔除mmTemp從strTemp中帶來的字符#13#10}
mmDecoded.CopyFrom(mmTemp,mmTemp.Size-2);
{對mmDecoded進行Base64編碼,由mmTemp返回編碼後的結果}
EncodeBASE64(mmTemp,mmDecoded);
{獲得Base64編碼後的字符串}
mmTemp.Position:=0;
strTemp.LoadFromStream(mmTemp);
{返回結果必須從strTemp[0]中獲得,如果使用strTemp.Text會
帶來不必要的字符#13#10}
Result:=strTemp[0];
end;
3、EncodeBASE64函數實現過程:
function EncodeBASE64(Encoded: TMemoryStream ; Decoded: TMemoryStream): Integer;
const
_Code64: String[64] =
(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/);
var
I: LongInt;
B: array[0..2279] of Byte;
J, K, L, M, Quads: Integer;
Stream: string[76];
EncLine: String;
begin
Encoded.Clear;
Stream := ;
Quads := 0;
{為提高效率,每2280字節流為一組進行編碼}
J := Decoded.Size div 2280;
Decoded.Position := 0;
{對前J*2280個字節流進行編碼}
for I := 1 to J do
begin
Decoded.Read(B, 2280);
for M := 0 to 39 do
begin
for K := 0 to 18 do
begin
L:= 57*M + 3*K;
Stream[Quads+1] := _Code64[(B[L] div 4)+1];
Stream[Quads+2] := _Code64[(B[L] mod 4)*16 + (B[L+1] div 16)+1];
Stream[Quads+3] := _Code64[(B[L+1] mod 16)*4 + (B[L+2] div 64)+1];
Stream[Quads+4] := _Code64[B[L+2] mod 64+1];
Inc(Quads, 4);
if Quads = 76 then
begin
Stream[0] := #76;
EncLine := Stream+#13#10;
Encoded.Write(EncLine[1], Length(EncLine));
Quads := 0;
end;
end;
end;
end;
{對以2280為模的余數字節流進行編碼}
J := (Decoded.Size mod 2280) div 3;
for I := 1 to J do
begin
Decoded.Read(B, 3);
Stream[Quads+1] := _Code64[(B[0] div 4)+1];
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1];
Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + (B[2] div 64)+1];
Stream[Quads+4] := _Code64[B[2] mod 64+1];
Inc(Quads, 4);
{每行76個字符}
if Quads = 76 then
begin
Stream[0] := #76;
EncLine := Stream+#13#10;
Encoded.Write(EncLine[1], Length(EncLine));
Quads := 0;
end;
end;
{“=”補位}
if (Decoded.Size mod 3) = 2 then
begin
Decoded.Read(B, 2);
Stream[Quads+1] := _Code64[(B[0] div 4)+1];
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + (B[1] div 16)+1];
Stream[Quads+3] := _Code64[(B[1] mod 16)*4 + 1];
Stream[Quads+4] := =;
Inc(Quads, 4);
end;
if (Decoded.Size mod 3) = 1 then
begin
Decoded.Read(B, 1);
Stream[Quads+1] := _Code64[(B[0] div 4)+1];
Stream[Quads+2] := _Code64[(B[0] mod 4)*16 + 1];
Stream[Quads+3] := =;
Stream[Quads+4] := =;
Inc(Quads, 4);
end;
Stream[0] := Chr(Quads);
if Quads > 0 then
begin
EncLine := Stream+#13#10;
Encoded.Write(EncLine[1], Length(EncLine));
end;
&