Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ini-Verschlüsselung mit Class Helper (https://www.delphipraxis.net/140684-ini-verschluesselung-mit-class-helper.html)

CodeX 23. Sep 2009 23:47


Ini-Verschlüsselung mit Class Helper
 
Vorab: Ich habe vor diesem Posting viel gesucht und nachgelesen. Und nein, ich habe keine passende Antwort gefunden.

Ich möchte ein gegebenes, größeres Projekt so erweitern, dass die geschriebenen Werte in eine Ini verschlüsselt abgelegt und gelesen werden können.
TIniFile ableiten und entsprechende Zusatzfunktionen einbauen würde Unmengen an Änderungen am bestehenden Code mit sich bringen. Das ist nicht gewünscht.

Das bedeutet, dass weiterhin ganz normal z.B. per
Delphi-Quellcode:
var ini: TIniFile;
begin
  ini := TIniFile.Create(IniName);
  try
    myString := ini.ReadString('Section','Ident','');
  finally
    ini.Free;
  end;
ein String ausgelesen werden können soll. Nur eben beim Lesen entschlüsselt.

Wie lässt sich das nun umsetzen?
Meinde Idee war einen Klassenhelfer zu verwenden. Da ich bislang noch nicht damit gearbeitet habe, stolpere ich damit durch die Gegend.

Ich dachte, das ginge jetzt so in der Art:

Delphi-Quellcode:
type
  TIniFileHelper = class helper for TIniFile
    function ReadString(const Section, Ident, Default: string): string;
  end;

implementation

function TIniFileHelper.ReadString(const Section, Ident, Default: string): string;
begin
  //hier später die Entschlüsselung

  inherited;
end;
Überschrieben wird das damit schonmal, aber das Erben der normalen Funktionalität klappt nicht. Ginge das, könnte ich an Stelle des Kommentars die Funktion erweitern.

Wie also statt des "inherited" Versuchs richtig?

omata 23. Sep 2009 23:54

Re: Ini-Verschlüsselung mit Class Helper
 
Delphi-Quellcode:
type
  TIniFileHelper = class(TIniFile)
    function ReadString(const Section, Ident, Default: string): string; override;
  end;
:
:
:
function TIniFileHelper.ReadString(const Section, Ident, Default: string): string;
begin
  Result:=inherited ReadString(Section, Ident, Default);
end;

CodeX 24. Sep 2009 00:06

Re: Ini-Verschlüsselung mit Class Helper
 
Wow, das ging ja schnell!

Also das override wollte er nicht:
Code:
E2137 Methode 'ReadString' nicht in Basisklasse gefunden
Nicht schlimm, wenn ich das weglasse, oder?

Aber die Result-Zuweisung war scheinbar genau richtig. Klappt wie es soll. Danke!

RWarnecke 24. Sep 2009 05:01

Re: Ini-Verschlüsselung mit Class Helper
 
Hallo zusammen,

mal vielleicht eine ganz dumme Frage, warum über eine Helper Klasse ? Ich kann das ganze doch auch so machen :
Delphi-Quellcode:
ini := TINIFile(NSFile);
try
  Passwort := Entschluesseln(ReadString('Section', 'Ident', 'Default'));

{ ... Hier passiert noch etwas mit dem Passwort ...}

finally
  ini.free;
end;
Warum sollte ich den Umständlichen Weg über eine extra Klasse gehen ? Welche Vorteile und Nachteile hat die Klasse gegenüber meiner Variante ?

CodeX 24. Sep 2009 05:11

Re: Ini-Verschlüsselung mit Class Helper
 
Wenn man den ver/entschlüsselten Wert nur ein Mal auslesen möchte, dann geht Deine Variante natürlich auch.
Brauchst Du das an hundert Stellen, musst Du alle hundert Stellen anpassen.
Mache ich das über die Helper-Klasse, brauche ich es nur ein Mal machen und mir in Zukunft keine Gedanken drüber zu machen.

mkinzler 24. Sep 2009 05:39

Re: Ini-Verschlüsselung mit Class Helper
 
Ein Class Helper ersetzt kein Veerbung. Man kann eine Klasse erweitern aber keine vorhandenen Funktionen verdecken

CodeX 24. Sep 2009 05:49

Re: Ini-Verschlüsselung mit Class Helper
 
Formel gesehen werden wohl tatsächlich keine Funktionen überschrieben. Aber praktisch gesehen schon.
Ich gebe zu, eine Vererbung oder Änderung des Originalquellcodes wären sauberer, aber auf diese Weise kann die Änderung "aufgesetzt" werden, ohne die Original-Funktionen oder den bereits gegebenen Quellcode anzurühren.

Genau das war ja meine Frage und omata hat ja die Lösung bereits gepostet. Ich habe im Anschluss ein wenig weitergebastelt und bin mit der Lösung zufrieden.

RWarnecke 24. Sep 2009 06:30

Re: Ini-Verschlüsselung mit Class Helper
 
Zitat:

Zitat von CodeX
Wenn man den ver/entschlüsselten Wert nur ein Mal auslesen möchte, dann geht Deine Variante natürlich auch.
Brauchst Du das an hundert Stellen, musst Du alle hundert Stellen anpassen.

Wieso denn das ? Wenn ich die Funktion Entschluesseln an hundert Stellen aufrufen und die Ausgabe und die Entschlüsselung ändern. Dann habe ich auch nur dort eine einzige Stelle wo ich es ändern muss. Ein weiterer Vorteil wäre noch, ich brauch jetzt nicht überlegen, wo habe ich die Helper Klasse verwendet und wo nicht.

mkinzler 24. Sep 2009 06:34

Re: Ini-Verschlüsselung mit Class Helper
 
Er meint wenn er hundert Werte hat, also 100 mal ini.ReadString() aufruft, muss er alle 100 Aufrufe entsprechend erweitern. Nimmt er einen Class Helper oder leitet eine eigene Klasse ab, welche das Entschlüsseln in ReadString() implementiert ist es einfacher.

himitsu 24. Sep 2009 07:06

Re: Ini-Verschlüsselung mit Class Helper
 
Mir war aber so, als wenn man mit den ClassHelpern nur erweitern kann, ABER nichts überschreiben,
also müßte er vermutlich seine Funktion ReadString anders nennen und überall die "neue" Funktion direkt aufrufen :gruebel:

Schließlich geht Overload NUR (egal wo), wenn sich die Funktions-Signatur (Parameter) unterscheidet.

RWarnecke 24. Sep 2009 07:30

Re: Ini-Verschlüsselung mit Class Helper
 
Zitat:

Zitat von mkinzler
Er meint wenn er hundert Werte hat, also 100 mal ini.ReadString() aufruft, muss er alle 100 Aufrufe entsprechend erweitern. Nimmt er einen Class Helper oder leitet eine eigene Klasse ab, welche das Entschlüsseln in ReadString() implementiert ist es einfacher.

Ok, habe ich soweit verstanden. Aber aus meinem Verständnis raus, müsste ich doch dann von der Klasse TIniFile ableiten oder nicht ? Das wäre doch eigentlich der saubere Weg oder nicht ?

mkinzler 24. Sep 2009 07:35

Re: Ini-Verschlüsselung mit Class Helper
 
Wenn es mit dem Class Helper funktionieren würde, wäre das der einfachste Weg, da dessen Unit nur eingebunden werden muss und die neue Funktionaltität dann in der TIniFile zur Verfügung steht

Tyrael Y. 24. Sep 2009 07:36

Re: Ini-Verschlüsselung mit Class Helper
 
Mal hier zum zeigen wozu ein Class helper gut ist.
Ist kopiert deshalb als Zitat.

Zitat:

Here's an example (no implementations, only class definition / method interface):

Delphi-Quellcode:
TTest = class
   procedure SomeProc;
end;
...

TTestHelper = class helper for TTest
   function SomeFunc : string;
end;
With the above class definitions, we can use the next code:

Delphi-Quellcode:
var
   t:TTest;
begin
  t:=TTest.Create;
  t.SomeFunc ;
...
even though SomeFunc was *not* defined in class TTest!

Hawkeye219 24. Sep 2009 07:54

Re: Ini-Verschlüsselung mit Class Helper
 
Hallo CodeX,

vielleicht hast du mit einer shadow class mehr Glück:

Delphi-Quellcode:
type
  TIniFile = class (IniFiles.TIniFile)
  public
    function ReadString (const aSection, aKey, aDefault: string): string;
  end;
 
function TIniFile.ReadString (const aSection, aKey, aDefault: string): string;
begin
  Result := '<' + inherited ReadString(aSection, aKey, aDefault) + '>';
end;
Am besten lagerst du Klassendefinition in eine eigene Unit aus. Du musst bei der Verwendung nur darauf achten, dass die neue Unit in der USES-Anweisung nach IniFiles auftaucht - falls du IniFiles überhaupt noch dort aufführen musst.

Gruß Hawkeye

himitsu 24. Sep 2009 08:00

Re: Ini-Verschlüsselung mit Class Helper
 
Wie gesagt, Class Helper können die Klassen nicht direkt ändern, sondern nur etwas NEUES dazuschmuggeln,

aber hier gibt es einen Trick :angel:

Die Unit muß als letzes (nach "IniFiles) dort eingebunden werden, wo die Ini-Klassen erstellt werden.
Dann wird TIniFile.Create ersetzt und es werden überall die neuen Funktionen verwendet,
da lokal (nachfolgend) immer die letzte Deklaration sichtbar ist und diese Funktionen praktischer Weise virtual sind. :)
Delphi-Quellcode:
unit EncyptedIniFiles;

interface
  uses IniFiles;

  type TIniFile = class(IniFiles.TIniFile)
    function ReadString(const Section, Ident, Default: string): string; override;
    procedure WriteString(const Section, Ident, Value: String); override;
  end;

implementation
  function TIniFile.ReadString(const Section, Ident, Default: string): string;
  begin
    Result := Decypted(inherited ReadString(Section, Ident, Default));
  end;

  procedure TIniFile.WriteString(const Section, Ident, Value: String);
  begin
    inherited WriteString(Section, Ident, Encypted(Value));
  end;

end.
Besser wäre es aber, wenn man DIESE TIniFile z.B. in TEncryptedIniFile umbenennt und dann überall TEncryptedIniFile.Create verwendet ... es geht aber auch wie oben, nur so wäre es "übersichtlicher".


Info: Die "angedeutete" Verschlüsselung muß aber noch "eingebaut" werden.

[edit]
och menno :cry:

CodeX 24. Sep 2009 12:03

Re: Ini-Verschlüsselung mit Class Helper
 
Ähm, was genau ist jetzt der Vorteil einer Shadow Class zu einem Class Helper?

Wie bereits geschrieben, wird auch bei einem Class Helper eine eigene gleichnamige Funktion bevorzugt behandelt, falls vorhanden. Das ist praktisch ein Überschreiben. Ich hab das ja wie gesagt schon eingebaut und es funktioniert.
Die Info, dass das so geht, hatte ich ursprünglich von hier: http://www.delphi-treff.de/sprachen/...helferklassen/

mkinzler 24. Sep 2009 12:07

Re: Ini-Verschlüsselung mit Class Helper
 
Zitat:

Ähm, was genau ist jetzt der Vorteil einer Shadow Class zu einem Class Helper?
Ein Class Helper erweitert eine Klasse. Im anderen Fall sind es 2 Klassen, wobei nicht die Methode, sondern die Klasse verdeckt wird. Hat den Vorteil echte OOP zu sein.

Uwe Raabe 24. Sep 2009 12:08

Re: Ini-Verschlüsselung mit Class Helper
 
Zitat:

Zitat von CodeX
Wie bereits geschrieben, wird auch bei einem Class Helper eine eigene gleichnamige Funktion bevorzugt behandelt, falls vorhanden. Das ist praktisch ein Überschreiben.

Bei deinem Class-Helper wird jeder Aufruf von ReadString auf die Helper-Methode umgeleitet. Die Aufrufe von ReadString innerhalb der Implementation von TIniFile (z.B. bei ReadInteger) landen aber weiterhin bei der Original-Routine. Bei der Shadow-Class wird auch hier die überschriebene Methode aufgerufen.

himitsu 24. Sep 2009 12:12

Re: Ini-Verschlüsselung mit Class Helper
 
Mit Class-Helpern kann man eine Klasse nachträglich um neue Funktionen erweitern, ohne die Implementation der Klasse zu verändern.

Dießes bedeutet aber, daß man keine Funktionen/Prozeduren überschreiben und auch keine neuen Klassenvariablen einbauen kann, denn dieses würde die Klasse ändern, was ja nicht geht.

Da du aber eine Funktion (hier ReadString) ersetzen willst, dann geht das also nicht.
Du könntest höchstens die Funktion überladen, also eine gleichnamige neue Funktion einbinden, welche aber, wie beim Überladen üblich, eine andere Signatur haben muß.

mkinzler 24. Sep 2009 12:13

Re: Ini-Verschlüsselung mit Class Helper
 
@Frank: Es scheint ja komischerweise zu funktionieren, obwohl es in der Theorie nicht funktionieren dürfte

himitsu 24. Sep 2009 12:21

Re: Ini-Verschlüsselung mit Class Helper
 
Zitat:

Zitat von mkinzler
@Frank: Es scheint ja komischerweise zu funktionieren, obwohl es in der Theorie nicht funktionieren dürfte

:shock:

CodeX 24. Sep 2009 12:27

Re: Ini-Verschlüsselung mit Class Helper
 
Warum soll das in der Theorie nicht gehen?
Selbst Borland schreibt in der Hilfe unter "Unterstützende Klassen":
"[Beispiel ...] - Aufgerufen wird die Funktion MyFunc der unterstützenden Klasse, da diese Vorrang vor dem eigentlichen Klassentyp hat."

himitsu 24. Sep 2009 12:28

Re: Ini-Verschlüsselung mit Class Helper
 
Delphi-Quellcode:
uses IniFiles;

type TIniFileHelper = class helper for TIniFile
    procedure WriteString(const Section, Ident, Value: String); override;
  end;

procedure TIniFileHelper .WriteString(const Section, Ident, Value: String);
begin
  inherited WriteString(Section, Ident, Decrypt(Value));
end;
deswegen geht es nicht
Zitat:

[DCC Fehler] Unit1.pas(28): E2137 Methode 'WriteString' nicht in Basisklasse gefunden

CodeX 24. Sep 2009 12:33

Re: Ini-Verschlüsselung mit Class Helper
 
Ich bin Dir sehr dankbar, dass Du Dich mit dem Problem befasst. Aber wenn ich nun schon ein paar Mal gesagt habe, DASS es geht (warum auch immer), dann beruht es darauf, dass ich es ausprobiert habe.

Zu Deinem letzten Posting: Schau mal in Posting #3 in diesem Thread.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:25 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