Results 1 to 6 of 6

Thread: EnDecrypt verschil in werking Delphi en Lazarus

  1. #1

    EnDecrypt verschil in werking Delphi en Lazarus

    Hallo,

    Onderstaand code fragment werkt wel in Delphi (D7) maar niet in Lazarus (versie 1.4). Enig idee hoe dit wel werkend te krijgen is?

    Code:
    function TForm1.EnDeCrypt(const Value : String) : String;
    var
      CharIndex : integer;
    begin
      Result := Value;
      for CharIndex := 1 to Length(Value) do
        Result[CharIndex] := chr(not(ord(Value[CharIndex])));
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Edit2.Text := EnDeCrypt(Edit1.Text);
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      Edit3.Text := EnDeCrypt(Edit2.Text);
    end;
    Met een vriendelijke groet, Frans

  2. #2
    Je EnDeCrypt() werkt nog prima. Dit kun je uittesten met Edit2.Text := EnDeCrypt(EnDeCrypt(Edit1.Text));
    Dat zal hetzelfde resultaat als Edit1.Text opleveren.

    Het probleem ligt echter in het feit dat jij een ansistring meegeeft aan de functie en een UTF8String terugkrijgt uit de functie (omdat je een not(char) doet. Eerste 7 bit van UTF8 zijn ANSI compatibel maar het 8e bit wordt gebruikt voor UTF8. Jou not(char) zal dus altijd het 8e bit omswitchen en dan is je string in één keer UTF8.

    Buiten het feit dat dit heel gevaarlijk is om te doen mag je deze UTF8 string eigenlijk niet gebruiken om weer te geven. Want stel je hebt 1 ANSI character. Daarvan wordt het 8e bit omgezet en in een UTF8 string hoort daar dan eigenlijk nog een character op te volgen (wat bij jouw string dus niet het geval is).

    Je kunt dit proberen (het werkte bij jouw voorbeeld wel) maar ik zou hier absoluut niet op durven vertrouwen:
    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Edit2.Text := AnsiToUtf8(EnDeCrypt(Edit1.Text));
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      Edit3.Text := EnDeCrypt(Utf8ToAnsi(Edit2.Text));
    end;
    Nogmaals... je kunt het resultaat van EnDeCrypt dus wel gebruiken om op te slaan in je database maar je moet de encrypted string dus niet gebruiken om het weer te geven in een edit. De onaangepaste EnDeCrypt'ed string kun je dan wel gewoon met EnDeCrypt weer terugkrijgen.
    (maar beter is het dus om een andere vorm van encryptie te gebruiken.)

  3. #3
    Senior Member Thaddy's Avatar
    Join Date
    Dec 2004
    Location
    Amsterdam
    Posts
    2,211
    Jou functie gaat er vanuit dat een char 1 byte lang is. Dat is in hogere delphiversies en Lazarus niet zo!

    Dit kan ook opgelost worden door de functie expliciet Ansi te maken:
    Code:
    function TForm1.EnDeCrypt(const Value : AnsiString) : AnsiString;
    var
      CharIndex : integer;
    begin
      Result := Value;
      for CharIndex := 1 to Length(Value) do
        Result[CharIndex] := chr(not(ord(Value[CharIndex])));
    end;
    Deze oplossing is backwards compatible met eerdere delphi versies.
    Werken aan Ansi support voor Windows is verspilde tijd, behalve voor historici.

  4. #4
    Quote Originally Posted by Thaddy View Post
    Dit kan ook opgelost worden door de functie expliciet Ansi te maken.
    Helaas gaat dat in Lazarus 1.4 nog steeds niet werken.
    Delphi heeft redelijk goed automatische string-conversie (unicode<->ansi) maar bij Lazarus werkt dat (nog) niet.
    Wat je hier dus doet (met Edit2.Text := EnDeCrypt(Edit1.Text) ) is een ansi-string (met 8 bits) toekennen aan een Edit2.Text (utf-8?). En dan krijg je in het genoemde voorbeeld een foutieve edit-veld. Je zult dus nog steeds handmatig de AnsiToUtf8/Utf8ToAnsi moeten doen.

    Code:
    Edit2.Text := AnsiToUtf8(EnDeCrypt(Edit1.Text));
    // ...
    Edit3.Text := EnDeCrypt(Utf8ToAnsi(Edit2.Text));
    Het blijft gewoon niet verstandig om een "encrypted password met 8 bit ansi" weer te geven via een TEdit (in Lazarus).

  5. #5
    Senior Member Thaddy's Avatar
    Join Date
    Dec 2004
    Location
    Amsterdam
    Posts
    2,211
    [QUOTE=rvk;346548]
    Code:
    Edit2.Text := AnsiToUtf8(EnDeCrypt(Edit1.Text));
    // ...
    Edit3.Text := EnDeCrypt(Utf8ToAnsi(Edit2.Text));
    Code:
    function TForm1.EnDeCrypt(const Value : RawByteString) : RawByteString;
    var
      CharIndex : integer;
    begin
      Result := Value;
      for CharIndex := 1 to Length(Value) do
        Result[CharIndex] := chr(not(ord(Value[CharIndex])));
    end;
    Wellicht?
    Werken aan Ansi support voor Windows is verspilde tijd, behalve voor historici.

  6. #6
    Quote Originally Posted by Thaddy View Post
    Wellicht?
    Ten eerste gaat dit met Lazarus 1.4 nog niet werken omdat die geen RawByteString kent (trunk wel).

    Ten tweede zal het niet veel uitmaken of je nu RawByteString of AnsiString gebruikt. Het probleem ligt erin dat je een 8bit character sequence (ansistring) gaat toekennen aan een TEdit.Text (die dus in Lazarus UTF-8 is). Als je dat niet met een expliciete conversie doet gaat het in Lazarus mis. Ik weet zo even niet of het in Delphi wel goed gaat maar die werkt intern niet met UTF-8 maar met UTF-16 en daar wordt een assignment van AnsiString naar (unicode)string volgens mij automatisch geconverteerd. In Lazarus dus niet ! Vandaar dat die UTF8ToAnsi en AnsiToUtf8 nodig zijn. Beter is het natuurlijk om de encrypted password helemaal niet meer aan een TEdit toe te kennen. De gebruiker kan er in een TEdit toch niets meer mee doen.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •