// Die Base64-Kodierung dient zum Übertragen von 8-Bit-Gruppen (Ansi) über
// Wege, die nicht 8-Bit sicher sind. Es werden die 256 möglichen Zustände
// eines Bytes in die 64 möglichen Zustände der Base64-Codierung umgewandelt.
// Hierfür werden jeweils drei Bytes zu einer 24-Bitfolge zusammengefasst
// und diese dann in vier 6-Bitgruppen unterteilt. Die 6-Bitgruppen werden
// an Hand einer Zeichentabelle ("Codepage-unabhängige ASCII-Zeichen" auch
// "Base64-Alphabet") umgesetzt und übermittelt. Dadurch wird jedoch das
// Ergebnis um 1/3 länger. Falls der Quelltext eine Bytelänge hat, welche
// nicht durch 3 teilbar ist, wird mit entsprechend vielen Nullen ergänzt,
// welche nach der Codierung (um Decodierfehler zu vermeiden) in '=' gewandelt
// werden. Das Base64-Codierungsverfahren wird z.B. bei der Übertragung von
// Email-Anhängen (Attachments) verwendet. Der so gewonnene Code kann sogar
// formatiert werden (Zeilen- oder Seitenumbrüche), da beim Decodieren alle
// Zeichen herausgefiltert werden, welche nicht zum Base64-Alphabet gehören.
// Getestet mit RS 10.4 unter W11
const
Tabelle: array [0 .. 63] of ansichar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'abcdefghijklmnopqrstuvwxyz0123456789+/';
function encode_b64(txt: ansistring): string;
var
rs, g: ansistring;
i, lg, lt: integer;
begin
rs := '';
lt := length(txt);
i := lt mod 3;
if i = 0 then
g := ''
else
g := ansistring(stringofchar(#0, 3 - i));
lg := length(g);
txt := txt + g;
inc(lt, lg);
i := 1;
while i < lt do
begin
rs := rs + Tabelle[ord(txt[i]) shr 2];
rs := rs + Tabelle[(ord(txt[i]) and 3) shl 4 or ord(txt[i + 1]) shr 4];
rs := rs + Tabelle[(ord(txt[i + 1]) and 15) shl 2 or ord(txt[i + 2]) shr 6];
rs := rs + Tabelle[ord(txt[i + 2]) and 63];
inc(i, 3);
end;
if lg = 0 then
exit;
rs := copy(rs, 1, length(rs) - lg) + ansistring(stringofchar('=', lg));
Result := string(rs);
end;
function decode_b64(txt: ansistring): string;
var
i, lt: integer;
a: array of integer;
rs: ansistring;
begin
rs := '';
i := 1;
while i <= length(txt) do
begin
if (pos(txt[i], Tabelle) = 0) then
delete(txt, i, 1)
else
inc(i);
end;
if txt = '' then
exit;
lt := length(txt);
setlength(a, lt + 3);
for i := 1 to lt do
a[i - 1] := pos(txt[i], Tabelle) - 1;
i := 0;
while i < lt do
begin
rs := rs + ansichar((a[i] shl 2) or (a[i + 1] shr 4));
rs := rs + ansichar((a[i + 1] shl 4) or (a[i + 2] shr 2));
rs := rs + ansichar(((a[i + 2] and 3) shl 6) or (a[i + 3] and 63));
inc(i, 4);
end;
a := nil;
Result := string(rs);
end;
// Text codieren...
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.caption := encode_b64(ansistring(Edit1.text));
end;
// ... und gleich wieder zurückwandeln
procedure TForm1.Button2Click(Sender: TObject);
begin
Label2.ShowAccelChar := false; // falls "&" im Text
Label2.caption := decode_b64(ansistring(Label1.caption));
end;