Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Base64Encode funktioniert nicht (https://www.delphipraxis.net/157662-base64encode-funktioniert-nicht.html)

Neutral General 20. Jan 2011 08:04

Base64Encode funktioniert nicht
 
Hallo,

Ich verstehe gerade nicht das Problem. Folgendes:

Delphi-Quellcode:
procedure Beispiel(AStream: TMemoryStream);
var tmp: TMemoryStream;
begin
  tmp := TMemoryStream.Create;
  try
    tmp.SetSize(CalcEncodedSize(AStream.Size));
    Base64Encode(AStream.Memory^,AStream.Size,tmp.Memory^);
    AStream.Clear; // <-- 
    AStream.Write(tmp.Memory^,tmp.Size);
  finally
    tmp.Free;
  end;
end;
An der markierten Stelle kracht es. Außerdem stehen in tmp nach Base64Encode nur 0-Bytes.
Was mache ich denn falsch?

Gruß
Neutral General

marabu 20. Jan 2011 11:38

AW: Base64Encode funktioniert nicht
 
Hallo Michael,

eigentlich müsste es in der Zeile davor "gekracht" haben, wenn ich deinen Code mit anderen Beispielen hier in der DP vergleiche.

Grüße vom marabu

Neutral General 20. Jan 2011 11:45

AW: Base64Encode funktioniert nicht
 
Hallo,

Also ich benutze diese Überladung von Base64Encode:

Delphi-Quellcode:
procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer);


Was ist denn das Problem?

marabu 20. Jan 2011 11:57

AW: Base64Encode funktioniert nicht
 
Die von Dir verwendete Überladung war klar zu sehen.
Ich hatte die DP nach Base64Encode durchsucht und diesen Beitrag gefunden.
Du dereferenzierst Memory, Matthias nicht.
Dieser Unterschied könnte über Erfolg und Misserfolg entscheiden.

Neutral General 20. Jan 2011 12:02

AW: Base64Encode funktioniert nicht
 
Ja.. den Beitrag habe ich schon gesehen.
Allerdings müsste seine Übergabe (ohne Dereferenzierung) falsch sein.

Was ich grade feststelle: Mit und ohne Dereferenzierung ist nach dem Aufruf AStream = nil :shock:

Blup 20. Jan 2011 13:23

AW: Base64Encode funktioniert nicht
 
Zitat:

Zitat von Neutral General (Beitrag 1076074)
Allerdings müsste seine Übergabe (ohne Dereferenzierung) falsch sein.

Ohne Dereferenzierung ist schon richtig:
Delphi-Quellcode:
var
  p: Pointer;
{...}
  p := tmp.Memory;
  Base64Encode(AStream.Memory, AStream.Size, p);

marabu 21. Jan 2011 07:50

AW: Base64Encode funktioniert nicht
 
Ich habe die Version 1.2 der Unit Base64 von sakura auf meiner Festplatte gefunden und ein paar Tests unterzogen. Vielleicht stelle ich mich momentan etwas ungeschickt an, aber das war dann damals, als ich Matthias unterstützen wollte, genau so.

Delphi-Quellcode:
const
  PASSWORD = 'top*secret';
var
  b64: string;
begin
  b64 := Base64Encode(PASSWORD);
  Base64Encode(PASSWORD, b64);
end;
Die beiden Aufrufe produzieren identische Ergebnisse. Der Code im Eröffnungsbeitrag dieses Threads verwendet Base64Encode mit der Signatur (const InBuf; InSize: Cardinal; var OutBuf). Das machen die beiden Aufrufe von mir intern auch. Ich habe deshalb den entsprechenden Code aus der Unit BASE64 extrahiert und ein wenig damit gespielt:

Delphi-Quellcode:
 
// das ist der Code von sakura

procedure Base64Encode(const InText: string; var OutText: string);
var
  InSize, OutSize: Cardinal;
  PIn, POut: Pointer;
begin
  InSize := Length(InText);
  OutSize := CalcEncodedSize(InSize);
  SetLength(OutText, OutSize);
  PIn := @InText[1];
  POut := @OutText[1];
  Base64Encode(PIn, InSize, POut);
end;

// hier habe ich den Ausgabepuffer lokal deklariert und gebe das
// Ergebnis im Eingabepuffer zurück. Allerdings verwende ich einen
// string und keinen MemoryStream.

procedure Base64(var InText: string);
var
  InSize, OutSize: Cardinal;
  PIn, POut: Pointer;
  OutText: string;
begin
  InSize := Length(InText);
  OutSize := CalcEncodedSize(InSize);
  SetLength(OutText, OutSize);
  PIn := @InText[1];
  POut := @OutText[1];
  Base64Encode(PIn, InSize, POut);
  InText := OutText;
end;
Die erste Prozedur funktioniert, wie von mir erwartet. Die zweite Prozedur funktioniert auf meinem Testsystem nicht. In EBX wird nicht die Länge übergeben, sondern ein Zeiger. Das führt, vermutlich wegen des viel zu hohen Wertes, zu aberwitzigen Folgefehlern. Für die weitere Untersuchung dieses Problems fehlen mir leider Motivation und Zeit. Vielleicht möchte sich jemand damit beschäftigen, der sich besser mit dem Inline-Assembler von Delphi auskennt.

Freundliche Grüße

Blup 21. Jan 2011 09:23

AW: Base64Encode funktioniert nicht
 
Base64Encode der zweite Paramaeter steht in EDX.
Richtig so:
Code:
  // load InSize (stored in EDX)
  mov EAX, InSize
Der Rückgabewert von Base64Decode wird nicht gesetzt, wenn ein leerer String übergeben wird.
Richtig so:
Code:
  mov EAX, InSize
  shr EAX, 2
  jz @@SuccessDone
Edit:
http://de.wikipedia.org/wiki/Base64:
Zitat:

In der Regel wird spätestens nach jeweils 76 ausgegebenen Zeichen, das entspricht 57 codierten Bytes, ein Zeilenumbruch eingefügt, welcher jedoch ansonsten für die Kodierung nicht von Belang ist.
Das wird in dieser Unit nicht berücksichtigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz