Este es el código de las rutinas de base64 (Mime.pas)
Código Delphi
[-]
unit Mime;
interface
uses Windows,SysUtils,Classes;
type EMimeError = class(Exception);
TMimeBytes = array[1..MAXINT] of Byte;
PMimeBytes = ^TMimeBytes;
function MIMEEncode(P:PMimeBytes;ASize:Integer):String;
function MIMEDeCode(ACode:String;var ADiscard:Integer):TMemoryStream;
implementation
type TMimeChars = array[0..63] of Char;
TMimeMasks = array[1..3] of Byte;
const MimeChars:TMimeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
MimeCodes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
BankMasks:TMimeMasks = ($03,$0F,$3F);
N1:TMimeMasks = ($FC,$F0,$C0);
N2:TMimeMasks = ($02,$04,$06);
N3:TMimeMasks = ($04,$02,0);
Pads:TMimeMasks = (0,2,1);
_BMC = 'Invalid Mime Code';
function MIMEEncode(P:PMimeBytes;ASize:Integer):String;
var i,k,ndx,Bank,AOffset:Integer;
APad:String;
procedure BuildCode;
var j:Integer;
begin
for j:=1 to 3 do
begin
k:=AOffset + j;
ndx:=(Bank or (P^[k] and N1[j]) shr N2[j]);
Result:=Format('%s%s',[Result,MimeChars[ndx]]);
Bank:=(P^[k] and BankMasks[j]) shl N3[j];
end;
if (k <= ASize) then Result:=Format('%s%s',[Result,MimeChars[Bank]]);
end;
begin
SetLength(Result,0);
i:=Pads[1 + ASize mod 3];
APad:=StringOfChar('=',i);
try
for k:=1 to i do P^[ASize + k]:=0;
inc(ASize,i);
i:=ASize;AOffset:=0; while (i > 0) do
begin
Bank:=0;
BuildCode;
dec(i,3);
inc(AOffset,3);
end;
except on E:Exception do raise EMimeError.Create(E.Message) end;
i:=Length(APad);
if (i > 0) then Delete(Result,Length(Result) - i + 1,i);
Result:=Result + APad;
end;
function MIMEDeCode(ACode:String;var ADiscard:Integer):TMemoryStream;
var i,ALen,AData:Integer;
ABytes:array[0..2] of Byte absolute AData;
begin
Result:=TMemoryStream.Create;
ALen:=Length(ACode);
case ALen of
0:ADiscard:=0;
1:ADiscard:=ord(ACode[1] = '=');
else case ACode[ALen - 1] of
'=':if (ACode[ALen] = '=') then ADiscard:=2 else raise EMimeError.Create(_BMC);
else ADiscard:=ord(ACode[ALen] = '=');
end;
end;
if (ADiscard > 0) then
begin
Delete(ACode,ALen - ADiscard + 1,ADiscard);
ACode:=ACode + StringOfChar('A',ADiscard);
end;
inc(ALen,ADiscard);
for i:=ALen downto 1 do if (Pos(ACode[i],MimeCodes) = 0) then Delete(ACode,i,1);
i:=1;
while (i <= ALen) do
begin
AData:=Pos(ACode[i + 3],MimeCodes) - 1 +
(Pos(ACode[i + 2],MimeCodes) - 1) shl 6 +
(Pos(ACode[i + 1],MimeCodes) - 1) shl 12 +
(Pos(ACode[i],MimeCodes) - 1) shl 18;
Result.WriteBuffer(ABytes[2],1);
Result.WriteBuffer(ABytes[1],1);
Result.WriteBuffer(ABytes[0],1);
inc(i,4);
end;
Result.Position:=0;
end;
end.