Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.049 Beiträge
Delphi 2009 Professional
|
AW: Base64/ Mime für Dateien
17. Sep 2017, 18:26
Die Methode von mir hatte zwei Fehler, was zu einem ungültigen Ergebnis führte. Hier die korrekte Version:
Delphi-Quellcode:
procedure Base64EncodeStream(Input, Output: TStream);
const
Base64: array[0..64] of Byte = (
65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,
97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,
48,49,50,51,52,53,54,55,56,57,43,47,$3D);
var
count: Byte;
temp: Cardinal;
i, j: Integer;
begin
Temp := 0;
Count := 3;
Output.Size := (Input.Size + 2) div 3 * 4;
for i := 0 to (Input.Size + 2) div 3 - 1 do
begin
Count := Input.Read(temp, 3);
temp := temp and $ff00 + temp shl 16 + temp shr 16 and $ff; // Endianness drehen (vereinfacht weil nur 3 Byte verwendet)
for j := 0 to Count do
begin
Output.Write(Base64[temp shr 18 and $3f], 1);
temp := temp shl 6;
end;
end;
for j := Count to 2 do
Output.Write(Base64[64], 1); // Schreibe ein Gleichzeichen zum Auffüllen
end;
Hier übrigens der Dekoder:
Delphi-Quellcode:
procedure Base64DecodeStream(Input, Output: TStream);
const
Base64: array[Byte] of ShortInt = (
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
var
count, b: Byte;
temp: Cardinal;
i: Integer;
begin
Temp := 0;
Count := 0;
Output.Size := Trunc(Input.Size / 4 * 3); // maximal möglichen Output reservieren
for i := 0 to Input.Size - 1 do
begin
Input.Read(b, 1);
if Base64[b] > -1 then
begin
temp := temp shl 6 or Byte(Base64[b]);
inc(Count);
if Count = 4 then
begin
temp := temp and $ff00 + temp shl 16 + temp shr 16; // Endianness drehen (vereinfacht weil nur 3 Byte verwendet)
Output.Write(temp, 3);
temp := 0;
Count := 0;
end;
end;
end;
if Count > 1 then // Rest behandeln, der kein 3er-Block ist (ein Base64-Rest kann nicht 1 lang sein)
begin
temp := temp shl (6 * (4 - Count));
temp := temp and $ff00 + temp shl 16 + temp shr 16;
Output.Write(temp, Count - 1);
end;
Output.Size := Output.Position; // Scheint entgegen der Dokumentation TMemoryStream.Memory nicht zu löschen
end;
Janni 2005 PE, 2009 PA, XE2 PA
|