Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Inhalt eines Memos binär speichern? (https://www.delphipraxis.net/128666-inhalt-eines-memos-binaer-speichern.html)

Yakumo500 3. Feb 2009 19:19


Inhalt eines Memos binär speichern?
 
Hallo,

Ich habe eine Frage bezüglich: Dateien binbär speichern.
Die binäre Datei soll dann nicht einfach von jedem Editor gelesen werden können wie zb Notepad.
Um einzelne Strings zu speichern und zu lesen habe ich bereits Code gefunden.

(Speichern:
Delphi-Quellcode:
var
  FileHandle : Integer;
  Version    : Integer;
  Period     : Integer;
  Digit      : Integer;
  c_copyright : String;
  Symbol     : String;
begin
  Version      := 400;
  Period       := 1;
  Digit        := 6;
  c_copyright  := '(C)opyright 2003, MetaQuotes Software Corp.';
  Symbol       := 'EURUSD';
  FileHandle   := FileCreate(Path);
  FileWrite(FileHandle, Version, SizeOf(Version));
  FileWrite(FileHandle, c_copyright, SizeOf(c_copyright));
  FileWrite(FileHandle, Symbol, SizeOf(Symbol));
  FileWrite(FileHandle, Period, SizeOf(Period));
  FileWrite(FileHandle, Digit, SizeOf(Digit));
  FileClose(FileHandle);
end;
Lesen:
Delphi-Quellcode:
var
  FileHandle : Integer;
  Version    : Integer;
  Period     : Integer;
  Digit      : Integer;
  c_copyright : String;
  Symbol     : String;
begin
  FileHandle   := FileOpen(Path, fmOpenRead);
  FileRead(FileHandle, Version, SizeOf(Version));
  FileRead(FileHandle, c_copyright, SizeOf(c_copyright));
  FileRead(FileHandle, Symbol, SizeOf(Symbol));
  FileRead(FileHandle, Period, SizeOf(Period));
  FileRead(FileHandle, Digit, SizeOf(Digit));
  FileClose(FileHandle);
end;
)

Aber wie sieht es aus wenn ich eine StringList habe, deren Länge sich ändern kann?

mr2 3. Feb 2009 20:18

Re: Inhalt eines Memos binär speichern?
 
dann musst Du eben als erstes die Länge der StringList in die Datei schreiben

mr2

tomsson74 3. Feb 2009 20:26

Re: Inhalt eines Memos binär speichern?
 
:?: Eine String List enthält Strings - wenn Du diese speicherst, wird jeder diese Datei mit Notpad öffnen können.

Auch die Datei aus deinem Beispiel lässt sich mit einem Editor öffnen, nur sind die ersten Zeichen eben binär. Der Text erscheint nach wie vor im Klartext.

/thomas

taaktaak 4. Feb 2009 07:10

Re: Inhalt eines Memos binär speichern?
 
Moin, Moin.
Die Frage ist m.E. unglücklich formuliert; was bedeutet "binär speichern" - alles wird doch letztlich binär gespeichert.
Du möchtest den Text aber offenbar verschleiern oder verschlüsseln. Da gibt es verschiedene Möglichkeiten; die Suche hier im Forum wird einiges dazu anzeigen.
Zunächst wäre die Frage zu klären, ob es lediglich darum geht, das Öffnen mit einem beliebigen Editor zu verhindern bzw. dort nur unleserliches anzuzeigen. Wenn also eine Verschleierung genügt, ist eine OR-Verknüpfung der einzelnen Zeichen bereits ausreichend. Soll es eine ernsthafte Verschlüsselung sein, wird es dann schon aufwendiger.

Yakumo500 4. Feb 2009 13:36

Re: Inhalt eines Memos binär speichern?
 
Ja ich meine das Verschlüsseln von Strings.
Und zu dem Quellcode: da muss statt einem Char Array String hin.
Ich berichtige es wenns geht.

@ mr2 Das habe ich probiert aber beim Lesen der Datei gibt es dann einen Fehler.

tomsson74 4. Feb 2009 15:27

Re: Inhalt eines Memos binär speichern?
 
Die Länge eines Strings ermittelst Du mit Length und nicht SizeOf.

SizeOf liefert bei einem String eine 4 - das ist die Länge des Zeigers auf den Speicherbereich in dem sich der String befindet.

Das Schreiben der Länge müsste in etwa so aussehen_

Delphi-Quellcode:
  (...)
  c_copyright : String;
  Symbol     : String;
  Laenge     : Integer // <------------- Eine Variable für die Länge des Strings
begin
  Version      := 400;
  Period       := 1;
  Digit        := 6;
  c_copyright  := '(C)opyright 2003, MetaQuotes Software Corp.';
  Symbol       := 'EURUSD';
  FileHandle   := FileCreate(Path);

  Laenge := Length(c_copyright); // <------------- Länge des Strings ermitteln
  FileWrite(FileHandle, Laenge, SizeOf(Laenge)); // <--------------- Länge des Strings speichern
  FileWrite(FileHandle, c_copyright, SizeOf(c_copyright)); // <----- Jetzt kommt der String ...
  (...)
Beim Lesen muss Du erstmal die Länge auslesen und dann den String mit dieser Länge lesen:

Delphi-Quellcode:
  (...)
  FileRead(FileHandle, c_copyright, Laenge);
  (...)
Ungetestet, aber so in etwa müsste das funktionieren.

/Thomas

Yakumo500 4. Feb 2009 18:28

Re: Inhalt eines Memos binär speichern?
 
Danke soweit funktioniert es.

Aber wenn ich jetzt den Inhalt eines Edits speichere und nach einem Neustart des Programms lade kommt ein Fehler:

Access violation at adress 7C91ED9E in module 'ntdll.dll'. Read of address 00BBFFFF

Ich habe keine Ahnung was dieser Fehler zu bedeuten hat.

Mein Code:

Delphi-Quellcode:

// ... uses usw. ...

var
  Form1: TForm1;
  Path : string = 'test.rmn';
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  FileHandle: Integer;
  Text: String;
  Laenge: Integer; // <------------- Eine Variable für die Länge des Strings
begin
  Text := Edit1.Text;

  FileHandle   := FileCreate(Path);

  Laenge := Length(Text); // <------------- Länge des Strings ermitteln
  FileWrite(FileHandle, Laenge, SizeOf(Laenge)); // <--------------- Länge des Strings speichern

  FileWrite(FileHandle, Text, SizeOf(Text));

  FileClose(FileHandle);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  FileHandle : Integer;
  Text : String;
  Laenge     : Integer;
begin
  FileHandle   := FileOpen(Path, fmOpenRead);

  FileRead(FileHandle, Laenge, SizeOf(Laenge));
  FileRead(FileHandle, Text, Laenge);

  FileClose(FileHandle);

  ShowMessage(Text);
end;

end.

DeddyH 4. Feb 2009 18:50

Re: Inhalt eines Memos binär speichern?
 
Zitat:

Delphi-Quellcode:
FileWrite(FileHandle, Text, SizeOf(Text));

Zitat:

Delphi-Quellcode:
FileRead(FileHandle, Text, Laenge);

Siehst Du den Unterschied zwischen Schreiben und Lesen? Ich könnte wetten, dass SizeOf(Text) immer 4 ist.

himitsu 4. Feb 2009 19:15

Re: Inhalt eines Memos binär speichern?
 
erstmal, wenn du in Text war reinladen willst, dann mußt die den Speicher zum Reinladen erstmal reservieren.

und Text zeigt nicht auf die Stringdaten, sindern auf den Stringzeiger


Delphi-Quellcode:
Laenge := Length(Text);
FileWrite(FileHandle, Laenge, SizeOf(Laenge));
FileWrite(FileHandle, Text[1], Leange); // und die länge muß auch stimmen

FileRead(FileHandle, Laenge, SizeOf(Laenge));
SetLength(Text, Laenge);
FileRead(FileHandle, Text[1], Laenge);

falls Text mal leer sein kann, mußt du das auch noch absichern, da Text[1] sonst eine Exception wirft, wenn du auf der erste, nicht vorhandene Zeichen zugreifen willst.
Delphi-Quellcode:
Laenge := Length(Text);
FileWrite(FileHandle, Laenge, SizeOf(Laenge));
If Laenge > 0 Then FileWrite(FileHandle, Text[1], Leange);

FileRead(FileHandle, Laenge, SizeOf(Laenge));
SetLength(Text, Laenge);
If Laenge > 0 Then FileRead(FileHandle, Text[1], Laenge);

Yakumo500 4. Feb 2009 19:31

Re: Inhalt eines Memos binär speichern?
 
Aber dann wird es bei mir nicht verschlüsselt angezeigt.

himitsu 4. Feb 2009 20:17

Re: Inhalt eines Memos binär speichern?
 
Zitat:

Zitat von Yakumo500
Aber dann wird es bei mir nicht verschlüsselt angezeigt.

ja, weil da nichts verschlüsselt ist.
du hattest nicht den Inhalt des Memos gespeichert, sondern andere Daten, wenn überhaupt was Richtiges an Daten dabei war.


Hier wird nur der Zeiger auf den String gespeichert,
Delphi-Quellcode:
FileWrite(FileHandle, Text, SizeOf(Text));
das ist so, als wenn du die Position speicherst, wo du auf einem Bild zu sehen bist,
aber beim Laden befindet sich dort nun ein anderes Bild (der Speicher ist dann ja ein anderer), dann kannst'e mit der Position, wo du auf'm alten Bild zu sehen warst nicht mehr viel anfangen, da du garnicht mehr an der Stelle bist (in Wirklichkeit bist du auf dem neuen Bild garnicht mehr drauf zu sehn)


Wenn das Ganze dazu diehnen sollte die Strings zu verschlüsseln, dann mußt du das vor'm Speichern selber verschlüsseln (siehe z.B. Hier im Forum suchenDEC).

Yakumo500 6. Feb 2009 21:18

Re: Inhalt eines Memos binär speichern?
 
Ich meine so etwas müsste es doch geben als Standard Funktion.

Bei C++ z.b. geht es so:

Delphi-Quellcode:
#include <iostream>
#include <fstream>

using namespace std;

int main ()
{
   int Highscore = 0;

   cout << "Wie hoch ist der Highscore: ";
   cin >> Highscore;

   ofstream Output ("Highscore.txt", ios::binary);
   Output.write ((char*) &Highscore, sizeof(Highscore));

   Output.close();
}
Gut ist jetzt nur integer aber man kann es mit dem Editor nicht mehr lesen.

himitsu 6. Feb 2009 22:02

Re: Inhalt eines Memos binär speichern?
 
tja, dirt wird die Binäre Darstellung des Integers gespeichert und die ist wirklich nicht so leicht lesbar,
aber die Binäre Darstellung eines Strings ist nunmal der Text selber und das ist nunmal lesbar, da der Editos diese binäre Darstellung auch kennt und diese dementsprechend "entschlüsselt" und dir den Text anzeigt :zwinker:

man könnte jetzt zwar z.B. einfach einen Unicode-BOM (Bei Google suchenByte Order Mark) vor einen AnsiText schreiben, dann würden alle Editoren, welche Unicode verstehen dieses auch "verschlüsselt" (nja, eigentlich nur falsch entschlüsselt) anzeigen, aber HEX-Editoren und Editoren, die kein Unicode verstehen, würden es dennoch "unverschlüsselt" anzeigen.

wie sehr willst du es denn verschlüsseln, bzw. wer soll es nicht entschlüsseln können?

das "Einfachst" wäre jetzt wohl eine "einfache" XOR-Verschlüsselung, wo ganz einfach Bits anhand eines "Schlüssels" umgedreht werden ... und wenn man die GLEICHEN Bits dann nochmal umdreht, dann kommt er Originaltext wieder zum Vorschein.

Delphi-Quellcode:
// Text von Variable "Text" verschlüsseln und speichern
S := Text;
For i := 1 to Length(S) do S[i] := Chr(Ord(S[i]) xor Ord('å'));
Laenge := Length(S);
FileWrite(FileHandle, Laenge, SizeOf(Laenge));
If Laenge > 0 Then FileWrite(FileHandle, S[1], Leange);

// gespeicherten Text in "Text" einlesen und entschlüsseln
FileRead(FileHandle, Laenge, SizeOf(Laenge));
SetLength(Text, Laenge);
If Laenge > 0 Then FileRead(FileHandle, Text[1], Laenge);
For i := 1 to Length(Text) do S[i] := Chr(Ord(Text[i]) xor Ord('å'));
schau dich einfach mal im Forum um, da gibt's einige Beispiele zu Verschlüsselungen.
- hier hab ich alles nur mit einem Zeichen verschlüsselt, also nach nur knapp 250 Versuchen hätte ich das auch ohne Schlüssel geknackt, aber man muß auch erstmal auf die Idee kommen, daß es auf diese Art verschlüsselt ist :angel2:

PS: da ich weiß wie ein Integer intern aufgebaut ist, kann ich den Highscore leicht ändern ... wenige Sekunden und ich hab die Höchstpunktzahl von nur 2.147.483.647 Pünktchen :stupid:

Yakumo500 6. Feb 2009 22:21

Re: Inhalt eines Memos binär speichern?
 
Ok Danke mir reicht eine zimelich einfache Verschlüsselung aus.

guidok 8. Feb 2009 09:05

Re: Inhalt eines Memos binär speichern?
 
Warum machst du es dir denn so kompliziert?

1. Schreib deine Strings in eine TStringList.
2. Geh die Liste Zeichen für Zeichen durch und "verschlüssele" jedes Zeichen mit eine XOR-Verknüpfung.
3. Rufe TStringList.SaveToFile auf

Das Laden geht mit TStringList.LoadFromFile, danach musst du wieder jedes einzelne Zeichen mit dem selben Wert XOR Verknüpfen und gut ist.

himitsu 8. Feb 2009 09:44

Re: Inhalt eines Memos binär speichern?
 
Zitat:

Zitat von guidok
1. Schreib deine Strings in eine TStringList.
2. Geh die Liste Zeichen für Zeichen durch und "verschlüssele" jedes Zeichen mit eine XOR-Verknüpfung.
3. Rufe TStringList.SaveToFile auf

da muß er allerdings aufpassen, daß er durch die Verschlüsselung keine Zeichen erhält, welche die StringList nicht mag (also keine #13, #10 und #0), was sich bei dieser Verschlüsselung allerdings nicht vermeiden läßt.

_frank_ 8. Feb 2009 12:51

Re: Inhalt eines Memos binär speichern?
 
du kannst auch TFileStream/TMemoryStream nehmen, die interessieren solche Sonderzeichen nicht.

Zitat:

Zitat von himitsu
PS: da ich weiß wie ein Integer intern aufgebaut ist, kann ich den Highscore leicht ändern ... wenige Sekunden und ich hab die Höchstpunktzahl von nur 2.147.483.647 Pünktchen :stupid:

mit cardinal gehts noch höher ;) negative Zahlen braucht man ja bei nem Highscore nicht. aber solche Werte kann man ja mittels Prüfsumme/Hash/etc. absichern.

Gruß Frank


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