Einzelnen Beitrag anzeigen

Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.081 Beiträge
 
Delphi 2009 Professional
 
#15

AW: Base64/ Mime für Dateien

  Alt 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
  Mit Zitat antworten Zitat