Entwickler-Ecke

Dateizugriff - Daten Binär schreiben


Luncustaf - Mo 14.04.03 11:27
Titel: Daten Binär schreiben
hi,

ich hab hier ein programm wo ich verschiedene informationen habe. diese sollen gespeichert werden. und zwar in ein eignes format.
wir machen zu dritt dieses projekt und wir wollen die sachen so wegschreiben - das man diese nicht einfach in einem texteditor lesen kann - nun hat einer meiner projektmitarbeiter gemeint ich solle diedtaen binär wegschreiben.

nun meine frage wie mache ich das? ich hab da nicht den geringsten plan wie ich am besten an diese sache rangehen soll.

gr€€tz


Aya - Mo 14.04.03 11:44

Hi,

schau dir mal den TFileStream in der Hilfe an.. ist auch nen Beispiel dazu bei ;)

Au'revoir,
Aya~


Klabautermann - Mo 14.04.03 12:48

Hallo,

ebenfalls angucken solltest du dir: ASSIGFILE, CLOSEFILE, FILE, BlockRead, BlockWrite, GetMem, FreeMem
anschauen.

Desweiteren könnte dieses Topic [http://www.delphi-forum.de/viewtopic.php?t=9624] für dich interessant sein.

Gruß
Klabautermann


Luncustaf - Mo 14.04.03 13:57

hi,

danke für den link und danke für euer antworten ich werde mir das zuhause mal anschauen :)

thanks a lot

gr€€tz


ShadowCaster - Mo 14.04.03 14:14

ich empfehle Blockread, Blockwrite, getmem, freemem ohne Stream zu verwenden, da nutzloser Overhead. Kann aber auch lästig sein, wenn du alles alleine proggen musst ohne Stream. Den Stream würde ich nur verwenden wenn es nicht auf Speed ankommt un du Ram sparen willst (lol, ich bin wohl ein bitfuchser :roll: ). Kommt wohl daher dass ich bis vor 3 Jahren noch auf einem 386er mit ner 120 MB Pladde und 4 MB Ram gehaust hab. Aber win95 lief....

naja, das hat ja nix mit dem Thema zu tun. Also, siehe den ersten Satz in meinem Kommentar. Dann hast dus ;)


Motzi - Mo 14.04.03 14:21

ShadowCaster hat folgendes geschrieben:
Den Stream würde ich nur verwenden wenn es nicht auf Speed ankommt

Ich glaub das Thema mit Streams und Speed hatten wir schon mal... :roll: ;)


ShadowCaster - Mo 14.04.03 15:40

ist ja auch egal. Jeder so wie er meint.


Luncustaf - Di 15.04.03 08:52

hi,

also ich hab mir jetzt das tutorial von eisenherz zu gemüte geführt klappt auch alles wunderbar also die ausgabe in einem eigenen dateiformat nur wenn ich das öffne mit einem editor kann man immernoch lesen was drinnen steht - ich hab mal ne andere datei von einem anderen programm aufgemacht und dort steht es so drinnen wie ich es gerne hätte und wzar nur irgendwelche zeichen - bei mir waren immer nur Trenner und dann richtige worte in der datei enthalten

wie bekomme ich das hin das das nur wie ein zusammgewürfelter buchstabensalat aussieht?


gr€€tz

PS: falls dies nicht gehen sollte ist es nicht weiter schlimm würde das nur gerne wissen :D


ShadowCaster - Di 15.04.03 09:06

du meinst, dass die Datei verschlüsselt ist? Ganz einfach. Nimm einfach ne Sinusspannung die du Byte für Byte berechnest. Dann legst du die mit XOR über den Stream (Byte für Byte). Du brauchst später nurnoch die gleichen Ausgangswerte für die Sinusspannung und die legst du wieder mit XOR über den Stream und dann hast du deine Daten wieder :wink:


SammySan - Di 15.04.03 09:15

Hmm, wir hatten ein ähnliche Aufgabenstellung vor kurzem in Informatik

Da es sich nur um Textdateien handelt dürfte Geschwindigkeit vernachlässigbar sein, also geht auch ein ziemlich simpler Mechanismus
also der Aufbau sieht so aus, du hast 2 Dateien, eine Datei die ver-oder entschlüsselt werden soll und eine Schlüsseldatei

also, du nimmst als dateityp byte :


Quelltext
1:
var sourcef, keyf, targetf:file of byte;                    


und weist diese mit assignfile zu, resetest beide und erstellst eine Zieldatei

nun nimmst du eine repeat until schleife


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure usekey;
var temp, temp2:byte
begin
repeat
if eof(keyf) then reset(keyf);  {sollte die keydatei kleiner sein als die zu verschlüsselte Datei wird die keyfile zwischendurch resetet werden müssen} 
read(temp, sourcef); //den bytewert aus der Quelldatei lesen
read(temp2, keyf); //den bytewert aus der Schlüsseldatei lesen
temp := temp xor temp2; //xor ist ein operator der Bitweise die beiden bytes addiert
write (temp, targetf); //das Ergebnis der Operation wird angewendet
until eof(sourcef); //wiederholen bis die Quelldatei am Ende ist



Damit kann man übrigends jede Art von Datei verschlüsseln

wenn du die Datei entschlüsseln willst musst du den Schlüssel einfach nochmal anwenden auf die verschlüsselte Datei


Ganz simpel oder ?
ist denk ich mal einfacher als stream verschlüsselung und auch genauso sicher


und nun setzt du auf den "Verschlüsseln Button" den aufruf der Prozedur

Moderiert von user profile iconKlabautermann: Code-Tags hinzugefügt.


Luncustaf - Di 15.04.03 10:00

werde ich mior zuhause mal zu gemüte führe :)

danke SammySan für den code werdsch mal schauen :) ob ich das checke.

danek shadowcaster für den ansatz :) aber ich weis net wirklich wie was ich mitdieser sinusspannung machen soll geschweige denn wo ich die herbekommen soll :)


gr€€tz


ShadowCaster - Di 15.04.03 14:16

Hier mein Ansatz. Die Funktion hat 4 Übergabeparameter:

- die zu verschlüsselnde Datei
- die Ausgangsdatei (die neu erstellt werden soll)
- falls die Ausgangsdatei existiert, überschreiben?
- die Sinusfrequenz, mit der verschlüsselt werden soll

Als Rückgabewert kommt, obs geklappt hat oder nicht. :wink: Getestet ist die Funktion auch und sie läuft. Als buffer wird ein 1 MB-Buffer verwendet. Ich hab in dem Beispiel mal einen Inputbuffer und einen Outputbuffer verwendet, um dir zu zeigen, wie man Eingangsdaten in Ausgangsdaten überführt und anschließend mit Blockwrite in eine Datei schreibt. Also du musst einfach nur über die verschlüsselte Datei nochmal die Funktion mit der gleichen Frequenz laufen lassen und dann wird sie wieder entschlüsselt.

mit Pointer^ sprichst du nicht den Speicherbereich, sondern den Wert ab dem Pointer an. Du kannst nach Integer, Double, etc. in alle Datentypen casten, wie du willst. Du kannst auch einen eigenen Typ definieren, z.B. einen Record. Da kannst du Records relativ einfach mit einer Block-Datei einlesen.


Quelltext
1:
2:
3:
4:
5:
6:
7:
type
  PCustomRecord = ^TCustomRecod;
  TCustomRecord = record
    Wert1 : Integer;
    Wert2 : Boolean;
    Wert3 : String[50]; // Strings sollten immer begrenzt sein beim Dateieinlesen oder du musst Byte für Byte lesen
  end;


Jetzt kannst du den Record aus dem Buffer lesen indem du folgendes machst:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var
EinleseListe : TList;

procedure xyz;
var CustomRecord : PCustomRecord;
begin
...

in der Leseschleife siehts so aus:

InPtr := Pointer(InBuf);
i := 0;
while i <= NumRead do
begin
  new(CustomRecord);
  EinleseListe.Add(CustomRecord);
  CustomRecord := TCustomRecord(InPtr^);
  InPtr := Pointer(Cardinal(InPtr) + SizeOf(CustomRecord);
  i := i + SizeOf(CustomRecord);
end;
...
end;



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
//Auf die Liste Greifst du so zu:
var
  CustomRecord : PCustomRecord;
  Wert : Integer;
begin
  if EinleseListe.Count > 0 then
  begin
    CustomRecord := PCustomRecord(EinleseListe.Items[0]);
    Wert := CustomRecord^.Wert1;
  end;
end;




Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
function Datei_encryption_decryption(InputFile : String; OutputFile : String; Overwrite : Boolean; Frequency : Integer) : Boolean;
var
  i : Integer;
  InFile          : File;    // Eingangsdatei
  OutFile         : File;    // Ausgangsdatei
  InBuf           : PChar;   // Eingangsbuffer
  InPtr           : Pointer; // Zeiger auf den InBuffer
  OutBuf           : PChar;   // Ausgangsbuffer
  OutPtr           : Pointer; // Zeiger auf den OutBuffer
  NRead, NWritten : Integer;
  w               : double;
  SoundValue      : byte;
const
  BufSize = 1000000; // 1000 K speicher wird als Buffer deklariert
  SampleRate : integer = 11025; // 8000, 11025, 22050, oder 44100 kann also geändert werden
begin
  Result := True;
  if (FileExists(OutputFile) AND Overwrite) OR NOT (FileExists(OutputFile)) then  // Existiert die Ausgangs datei und überschreibenaktiviert?
  begin
    AssignFile(InFile, InputFile);
    AssignFile(OutFile, OutputFile);
    try
      Rewrite(OutFile, 1);
    except
      Result := False;   // die Ausgabedatei kann nicht geöffnet werden
      exit;
    end;
    try
      Reset(InFile, 1);
    except
      Result := False;   // die Eingangsdatei kann nicht geöffnet werden
      exit;
    end;
    try
      GetMem(InBuf, BufSize);
      GetMem(OutBuf, BufSize);
    except
      MessageDlg('Zu wenig Arbeitsspeicher für diese Operation. Bitte beenden Sie einige Anwendungen, damit Arbeitsspeicher für diesen Prozess frei wird.', mtError, [mbOk], 0);
      CloseFile(InFile);
      CloseFile(OutFile);
      exit;
    end;
    w := 2 * Pi * Frequency;  // omega
    repeat
      BlockRead(InFile, InBuf^, BufSize, NRead);
      InPtr := Pointer(InBuf);
      OutPtr := Pointer(OutBuf);
      for i := 0 to NRead - 1 do
      begin
        SoundValue := 127 + trunc(127 * sin(i * w / SampleRate));
        Byte(OutPtr^) := Byte(InPtr^) XOR SoundValue;
        InPtr := Pointer(Cardinal(InPtr) + 1);
        OutPtr := Pointer(Cardinal(OutPtr) + 1);
      end;
      BlockWrite(OutFile, OutBuf^, NRead, NWritten);
    until (NRead = 0) or (NWritten <> NRead);
    CloseFile(InFile);
    CloseFile(OutFile);
  end else begin
    Result := False;
  end;
end;


Achja, das ganze Beispiel bewusst ohne stream. Es zeigt mal wieder wie unnütz Streams in diesem Falle sind. Mit Streams wäre der Code 1/3 länger geworden und ich hätte noch einen Haufen unnötigen Overhead ;) Ohne Streams zu programmieren ist eine Philosphie wie ohne VCL zu programmierenn. 8)


Luncustaf - Di 15.04.03 14:35

puh


danke für den code werde ich mir mal in ruhe reinzihen hier auf arbeit geht das net :)

ich werde es auf jedenfall probieren. und wenn es klappt dir bescheid geben

danke vielmals


gr€€tz


ShadowCaster - Di 15.04.03 14:54

kein Problem :roll: