Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Fragen zu TFileStream (https://www.delphipraxis.net/120175-fragen-zu-tfilestream.html)

Dbof 6. Sep 2008 18:03


Fragen zu TFileStream
 
Hallo an alle !

Ich arbeite seit gestern erst an einem kleinem (Verschlüsselungs-)Programm, welches mir folgendes ermöglicht:

Ich habe 1 Datei, die verschlüsselt werden soll(Datei X) und eine 'Schlüsseldatei'(Datei K), um Datei X zu entschlüsseln. Meine Pläne sind, dass ich die ersten 512 KB aus Datei K auslese, dann Datei X xor 512 KB und dann soll Datei X durch das Ergebnis ersetzt werden. Am Ende befinden sich also eine unleserliche Datei X und eine nichtveränderte Datei K.

Leider hab ich nicht die geringste Ahnung, wie ich das realisieren soll. Durch die Forumsuche habe ich von TFileStream erfahren, doch weiß nicht, wie ich das genau anwenden soll. Kann mir jemand vielleicht zeigen, wie ich das hinbekommen könnte?


Delphi-Quellcode:
procedure Crypt(Original, Keyfile, NewFile : String);
var input, xorbyte : TFileStream;
begin

  //Die Originaldatei wird zum Bearbeiten geöffnet
  input := TFileStream.Create(Original, fmOpenReadWrite);

  //Die Schlüsseldatei wird zum LESEN geöffnet
  xorbyte := TFileStream.Create(KeyFile, fmOpenRead);

  //Lese 512 KB aus Schlüsseldatei
  xorbyte.Read(xorbyte, 524288);//512 KB or 0,5 MB

  //Hier fehlt das XOR mit der Originaldatei,
  //Ich weiß nicht, wie ich das Ergebnis in den Buffer speichern soll
  //So hatte ich mir das vorgestellt:
  //input.WriteBuffer((input xor xorbyte), 524288);
  //Schreibe das Ergebnis aus input xor xorbyte in die Originaldatei

 
  //Speicher wieder freigeben
  xorbyte.Free;
  input.Free;

end;
Ich weiß, dass vielleicht der ganze Code Quatsch ist und dass ich keine Ahnung von TFileStream oder XOR habe, aber bei mir heißt die Divise 'learning-by-doing' und da ich jetzt genau hier hänge...wer gibt mir Aushilfe?

rollstuhlfahrer 6. Sep 2008 18:15

Re: Zweifel zu TFileStream
 
HI,

als erstes mal würde ich dir Vorschlagen, deine Schlüssel in ein Array of Char zu laden. Das lässt sich mit der Funktion Read bewerkstelligen. Dann brauchst du eine Schleife, die eine Datei lesend und schreibend öffnet. Von dieser liest du ein Zeichen, geht das Zeichen zurück und überschreibst das Zeichen mit dem verschlüsselten Wert. Das sieht dann so aus:

Delphi-Quellcode:
procedure EncryptFile(XFile, KFile: String);
var
  fkey, fxfile: TFilestream;
  keys: array[0..524287] of Char; // deine Menge weniger 1
  i: Cardinal;
  buffer: Char;
begin
  fkey := TFileStream.Create(kfile, fmOpenRead);
  fkey.Read(keys, 524288); // nun wieder vollzählig
  fkey.Free;  // wird nicht mehr benötigt, da im Speicher

  fxfile := TFileStream.Create(xFile, fmOpenReadWrite);
  for i := 1 to fxfile.Size do
  begin
    fxfile.Read(buffer, 1);
    fxfile.Position := fxFile.Position - 1;
    fxFile.Write(Chr(Ord(buffer) XOR Ord(keys[(i-1) mod 524287])), 1); // XOR
  end;
  fxfile.Free;
end;
Frei im Editor getippt. Kann Fehler enthalten.

Bernhard

EDIT: "ZWEIFEL" drückst du keine aus. Also kannst du dir auch gleich noch einen neuen Namen für das Thema suchen

Dbof 13. Okt 2008 14:39

Re: Fragen zu TFileStream
 
gut, danke, aber

Delphi-Quellcode:
fxFile.Write(Chr(Ord(buffer) XOR Ord(keys[(i-1) mod 524287])),{HIER} 1); // XOR
es erscheint ein Fehler bei der markierten Stelle.

[Fehler] test.pas(93): Variable erforderlich

Was für eine Variable wird da verlangt?

Dbof 13. Okt 2008 16:15

Re: Fragen zu TFileStream
 
hat keiner eine Antwort für mich?

smallsmoker 13. Okt 2008 17:10

Re: Fragen zu TFileStream
 
Zitat:

hat keiner eine Antwort für mich?
1. pushen ist verboten (innerhalb von 24 stunden)
2. wenn einer eine antwort hätte warum sollte er sie nicht posten ? und wenn er das nicht will wird auch deine nachfrage nicht helfen, oder ?

sirius 13. Okt 2008 17:29

Re: Fragen zu TFileStream
 
Diesen Ausdruck (bzw. dessen Ergebnis):
Delphi-Quellcode:
Chr(Ord(buffer) XOR Ord(keys[(i-1) mod 524287]))
...schreibst du mal schön in eine Variable und übergibst diese.

Was anderes steht ja auch nicht in der Fehlermeldung.

Uwe Raabe 13. Okt 2008 17:29

Re: Fragen zu TFileStream
 
So sollte es gehen (übrigens auch mit Delphi 2009):

Delphi-Quellcode:
procedure EncryptFile(XFile, KFile: String);
var
  fkey, fxfile: TFilestream;
  keys: array[0..524287] of Byte; // deine Menge weniger 1
  i: Cardinal;
  buffer: Byte;
begin
  fkey := TFileStream.Create(kfile, fmOpenRead);
  fkey.Read(keys, 524288); // nun wieder vollzählig
  fkey.Free;  // wird nicht mehr benötigt, da im Speicher

  fxfile := TFileStream.Create(xFile, fmOpenReadWrite);
  for i := 0 to fxfile.Size-1 do
  begin
    fxfile.Read(buffer, 1);
    fxfile.Position := fxFile.Position - 1;
    buffer := buffer XOR keys[i mod 524287];
    fxFile.Write(buffer, 1); // XOR
  end;
  fxfile.Free;
end;
Wesentlich performanter und mit unterschiedlichen Schlüsseldateilängen geht das aber so (funktioniert nur, wenn die zu verschlüsselnde Datei komplett in den Speicher geht!):

Delphi-Quellcode:
procedure EncryptFile(const XFile, KFile: String);
var
  fileStream: TFilestream;
  memStream: TMemoryStream;
  keys: array of Byte;
  keySize: Cardinal;
  i: Cardinal;
  buffer: Byte;
begin
  { Schlüsseldatei in Byte-Array einlesen }
  fileStream := TFileStream.Create(kfile, fmOpenRead);
  try
    keySize := fileStream.Size;
    SetLength(keys, keySize);
    fileStream.Read(keys, keySize);
  finally
    fileStream.Free;
  end;

  memStream := TMemoryStream.Create;
  try
    { xFile Datei in MemoryStream kopieren }
    fileStream := TFileStream.Create(xFile, fmOpenRead);
    try
      memStream.CopyFrom(fileStream, fileStream.Size);
      memStream.Position := 0; // wieder auf Start setzen
    finally
      fileStream.Free;
    end;

    fileStream := TFileStream.Create(xFile, fmOpenWrite);
    try
      for i := 0 to memStream.Size - 1 do
      begin
        memStream.Read(buffer, 1);
        buffer := buffer XOR keys[i mod keySize]; // XOR
        fileStream.Write(buffer, 1);
      end;
    finally
      fileStream.Free;
    end;
  finally
    memStream.Free;
  end;
end;

Dbof 13. Okt 2008 20:15

Re: Fragen zu TFileStream
 
Danke an alle...
meine Anwendung lässt sich nun kompilieren

Das ist der Code, den ich nun benutze(falls ihn jemand anderes braucht:

Delphi-Quellcode:
procedure Crypt(XFile, KFile: String);  //Durch die freundliche Unterstützung von rollstuhlfahrer und Uwe Raabe entstanden
var
  fkey, fxfile: TFilestream;
  keys: array[0..524287] of Char; // deine Menge weniger 1
  i: Cardinal;
  buffer: Char;
begin
  fkey := TFileStream.Create(kfile, fmOpenRead);
  fkey.Read(keys, 524288); // nun wieder vollzählig
  fkey.Free;  // wird nicht mehr benötigt, da im Speicher

  fxfile := TFileStream.Create(xFile, fmOpenReadWrite);
  for i := 0 to fxfile.Size -1 do
  begin
    fxfile.Read(buffer, 1);
    fxfile.Position := fxFile.Position - 1;
    buffer := Chr(Ord(buffer) XOR Ord(keys[(i-1) mod 524287]));
    fxFile.Write(buffer, 1); // XOR
  end;
  fxfile.Free;
end;

Danke vor allem an Uwe Raabe

Uwe Raabe 13. Okt 2008 21:32

Re: Fragen zu TFileStream
 
Da ist noch ein kleiner Fehler drin!

Delphi-Quellcode:
for i := 0 to fxfile.Size -1 do
  ...
  buffer := Chr(Ord(buffer) XOR Ord(keys[(i-1) mod 524287]));
Für i=0 unterschreitest du den Array-Bereich von keys!

Ich würde dir auch empfehlen, bei keys und buffers lieber Byte statt Char zu verwenden.

Delphi-Quellcode:
 
keys: array[0..524287] of Byte;
buffer: Byte;
Zum Einen wird damit die XOR-Anweisung leichter lesbar

Delphi-Quellcode:
buffer := buffer XOR keys[i mod 524287];
und zum Anderen ist der Code damit auch kompatibel zu Delphi 2009!


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