Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Schnellere XOR Operation (https://www.delphipraxis.net/123165-schnellere-xor-operation.html)

Dbof 28. Okt 2008 21:03


Schnellere XOR Operation
 
Einen schönen Abend!

Ich nutze die folgende Funktion, um 1 Datei mit einem Teil der 2. Datei zu "verschlüsseln", wobei dies nur eine simple XOR-Verschlüsselung ist:

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;
Wenn ich diese Funktion in mein Programm integriere, läuft sie gut. Das jedoch nur bei "kleinen" Schlüsseldateien. Will ich eine größere Datei verwenden, braucht das Programm ewig. Dabei lässt sich auch das GUI kaum mehr nutzen, bzw. stürzt völlig ab. Kann ich was dagegen tun? Oder gibt es vielleicht eine "echte" Verschlüsselungsmethode, die schnell genug ist? Die zu ver- und entschlüsselnden Dateien sollten beliebig groß sein können.

Danke im Voraus :dp:

alzaimar 28. Okt 2008 21:05

Re: Schnellere XOR Operation
 
Du liest immer nur ein Zeichen ein. Mach das mal mit einem Puffer (z.B. 8k). Dann geht das auch schneller.

Dbof 28. Okt 2008 21:47

Re: Schnellere XOR Operation
 
Könntest du mir denn vielleicht sagen, was ich unter Puffer verstehen soll? Bitte nicht auf die Suchfunktion verlinken, hab schon hier, auf delphi-treff und in der Delphi-Hilfe gesucht...

Meinst du damit, die Datei mit einem Stream zu durchlaufen oder versteh ich das falsch? Bitte um Code-Beispiele oder irgendwelche Stichwörter.


Danke.

Neutral General 28. Okt 2008 21:51

Re: Schnellere XOR Operation
 
Hi,

Ich würds so machen:

Lad (wenn die Datei nicht soooooooo groß ist) die komplette Datei in den Speicher, Xore sie und schreib dann die ganze gexorte Datei wieder zurück.

jfheins 28. Okt 2008 22:06

Re: Schnellere XOR Operation
 
Ein kleines Beispiel:
Delphi-Quellcode:
procedure ReplaceFile(FileName: String)
var
  fs: TFileStream;
  mem: TmemoryStream;
  i: Integer;
begin

  mem := TMemoryStream.Create();

  fs := TFileStream.Create(FileName, fmOpenReadWrite or fmShareExclusive);
  try
    mem.CopyFrom(fs, 0);
   
    // Mach etwas mit memstream
   
    fs.CopyFrom(mem, 0);
   
  finally
    fs.Free;
    mem.Free;
  end;
end;
(Bin mir nicht sicher, ,ob das kompiliert, aber so könnte eine Pufferung aussehen. In diesem Fall wird die ganze Datei geladen. Das geht solange gut, wie die Datei wesentlich kleiner als der RAM ist.)

taaktaak 28. Okt 2008 22:15

Re: Schnellere XOR Operation
 
tja, und dann gäbe es auch noch die uralt-Befehle BlockRead() und BlockWrite() - die Delphi-Hilfe zeigt da ein schönes Beispiel. Den Puffer kann man in der Größe flexibel gestalten und zwischen dem BlockRead() und dem BlockWrite() liesse sich das XORen sehr schön placieren :wink:

alzaimar 29. Okt 2008 07:25

Re: Schnellere XOR Operation
 
Ein Puffer ist ein Datenbereich im Speicher, mit dem man schnell(er) arbeiten kann. Die Methode 'TFileStream.Read' liest ja nicht nur ein Zeichen, sondern kann auch mehrere Zeichen einlesen. Die Methode liefert außerdem die Anzahl der gelesenen Zeichen. Sobald dieser Wert < als der zu lesende Wert ist, ist die Datei am Ende.

Die Methode 'TFileStream.Write' schreibt den (veränderten) Puffer dann wieder in eine Datei.

Zitat:

Zitat von Dbof
Könntest du mir denn vielleicht sagen, was ich unter Puffer verstehen soll? Bitte nicht auf die Suchfunktion verlinken, hab schon hier, auf delphi-treff und in der Delphi-Hilfe gesucht...

Von Google hast Du nix gesagt :mrgreen:

Dbof 2. Jan 2009 22:42

Re: Schnellere XOR Operation
 
Ist schon 2 Monate her, aber ich hatte keine Zeit, mich mit Delphi zu beschäftigen, aber nun bin ich wieder da.

Ich bin euren Ratschlägen gefolgt und habe den Puffer vergrößert und alles mühevoll angepasst.

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

  CopyFile(PChar(OriginalFile), PChar(NewFile), FALSE);

  fxfile := TFileStream.Create(NewFile, fmOpenReadWrite);
  SaveProgress.MaxValue := fxfile.Size;
  SaveProgress.Progress := SaveProgress.MinValue;
  calc := fxfile.Size div 2048;

  for i := 0 to calc do
  begin
    realbuffer := fxfile.Read(buffer, 2048);
    fxfile.Position := fxfile.Position - realbuffer;
    buffer := buffer XOR keys[(i mod 524287)]; // XOR
    fxfile.Write(buffer, realbuffer);
    SaveProgress.Progress := SaveProgress.Progress + realbuffer;
    SaveProgress.Refresh;       //Progressbar aktualisieren
    Application.processmessages;  //Fenster noch verwendbar
  end;

  fxfile.Free;
  ShowMessage(Name1.Text + ' was mixed with ' + Name2.text);
end;
Nun ist eigentlich alles genauso, wie ich es will. Nur ein paar Sachen klappen nicht.
  • Ich kann die Puffergröße nicht höher als 2KB einstellen(also schon bei 4KB gibt die Prozedur den Geist auf)
  • Am Ende der Prozedur, also nach der MsgBox gibt's eine AV.

Zur Puffergröße: Wovon hängt die erlaubte Puffergröße ab? Ich hab es mit >2KB versucht, doch dann passiert, dass die Progressbar nichts anzeigt, dann sofort die Meldung angezeigt wird, keine AV, aber beim 2.ten Aufrufen der Prozedur gibt's eine AV:
Zitat:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt test.exe ist eine Exception der Klasse EFOpenError aufgetreten. Meldung: 'Datei C:\test.jpg kann nicht geöffnet werden. Das System kann die angegebene Datei nicht finden'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
---------------------------
Aber die Datei ist auf jeden Fall vorhanden.


Die AV zum 2ten Problem:
Zitat:

---------------------------
Benachrichtigung über Debugger-Problem
---------------------------
In Projekt C:\test.exe trat ein Problem mit folgender Meldung auf: 'Zugriffsverletzung bei 0xd1b51878: Lesen von Adresse 0xd1b51878'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK
---------------------------

omata 2. Jan 2009 22:47

Re: Schnellere XOR Operation
 
Zitat:

Zitat von Dbof
Wovon hängt die erlaubte Puffergröße ab?

Dazu sollte man vielleicht wissen, dass die lokalen Variablen einer Prozedur/Funktion auf dem Stack abgelegt werden. Es ist also vielleicht nicht so sinnvoll dort riesige Datenkonstrukte zu hinterlegen.

Dbof 2. Jan 2009 23:44

Re: Schnellere XOR Operation
 
Zitat:

Zitat von omata
Zitat:

Zitat von Dbof
Wovon hängt die erlaubte Puffergröße ab?

Dazu sollte man vielleicht wissen, dass die lokalen Variablen einer Prozedur/Funktion auf dem Stack abgelegt werden. Es ist also vielleicht nicht so sinnvoll dort riesige Datenkonstrukte zu hinterlegen.

Heißt soviel wie: "So viel Speicher ist für den Buffer nicht reserviert!" Oder?

Zitat:

FileStream alleine ist ziemlich uneffektiv, die Puffergröße ist hier von der Windows-API abhängig. Ergebnis 40-fache Zugriffszeit. Auszug von http://delphi.pjh2.de/


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:52 Uhr.
Seite 1 von 2  1 2      

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