Autor |
Beitrag |
DevilFish
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 16.09.08 00:17
Hallo Leute,
ich bin dabei ein Program zu schreiben welches Dateien im BlowFish verfahren verschlüsselt. Das funktioniert soweit auch ganz gut, allerdings bin ich gerade dabei den Algorithmus etwas zu optimieren und habe dazu ein Fragen. VLt. kann ja jemand helfen.
Gibt es eine Möglichkeit 4 Byte-Variabeln, Bit für Bit, in eine Integer-Variable zu schreiben/kopieren. Und das Ganze auch wieder zurück(Integer -> 4 Byte). Ich suche ein möglichst schnelles Verfahren, da das ganze in einer Schleife immer wieder abläuft.
zB. 11001100 + 10101010 + 00110011 + 00001111 = 11001100/10101010/00110011/00001111
Byte1 + Byte2 + Byte3 + Byte4 = Integer
Meine Lösung:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| var L : LongWord; Buffer : array[1..4] of Byte; . . . For a := 1 to 4 do begin inc(L, Buffer[a]); If b < 4 then L := L shl 8; end;
For a := 4 downto 1 do begin Buffer[a] := L mod 256; If a > 1 then L := L shr 8; end; |
Hat jemand vlt. eine bessere Idee. Würd mich freuen.
mfg DevilFish
Moderiert von AXMD: Delphi-Tags hinzugefügt
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Di 16.09.08 01:20
Bin mir jetzt nich ganz sicher wie die Bytes da so im speicher rumliegen, aber soweit ich weis wenn du die als array deklarierst liegen die hintereinander, und folglich müsstest du das direkt als Integer ansprechen können, in dem du den Zeiger auf das erste Byte in einen Integer-Zeiger castest.
Evtl. wäre es auch denkbar es mit einem varianten record zu machen. (--> case-anweisung in records).
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 16.09.08 08:05
Moin!
Tilman hat folgendes geschrieben: | Evtl. wäre es auch denkbar es mit einem varianten record zu machen. (--> case-anweisung in records). |
Ja, das geht. Z.B. so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| type T4Bytes = packed record case Integer of 0: (Bytes: array[0..3] of Byte); 1: (Total: Cardinal); end;
implementation
procedure TForm1.Button1Click(Sender: TObject); var Test: T4Bytes; begin Test.Total := $DEADBEEF; ShowMessageFmt('%p%s%x.%x.%x.%x', [Pointer(Test.Total),#13, Test.Bytes[0],Test.Bytes[1], Test.Bytes[2],Test.Bytes[3]]); end; | Aber Vorsicht! Intels sind big-endian CPUs! Die Werte sind also genau andersrum in Speicher, als beim binären Zahlensystem, Motorola-CPUs, Network-Byte-Order und wie von dir erwartet.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 16.09.08 09:24
Ansonsten sollte auch sowas funktionieren:
Delphi-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:
| var IntVal: Integer; B1, B2, B3: Byte;
begin B1 := 1; B2 := 2; B3 := 3; IntVal := 0; Inc(IntVal, B1); IntVal := IntVal shl 8; Inc(IntVal, B2) IntVal := IntVal shl 8; Inc(IntVal, B3)
B3 := 0; B2 := 0; B1 := 0;
B3 := IntVal and $FF; IntVal := IntVal shr 8; B2 := IntVal and $FF; IntVal := IntVal shr 8; B1 := IntVal and $FF; end; |
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 16.09.08 09:39
Moin!
baka0815 hat folgendes geschrieben: | Ansonsten sollte auch sowas funktionieren: |
Wo ist denn da jetzt der Unterschied zur Lösung von DevilFish?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 16.09.08 09:41
|
|
hjm
Hält's aus hier
Beiträge: 4
|
Verfasst: Di 16.09.08 10:57
Hallo DevilFish,
warum machst Du es nicht einfach mit Schiebeoperationen
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var b0,b1,b2,b3 : Byte; GetParamVal : Long; ...
GetParamVal := (b3 SHL 24) + (b2 SHL 16) + (b1 SHL 8) + b0; |
sollte eingentlich recht zügig gehen, da nur Grundop's.
Grüße
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Di 16.09.08 11:06
hjm hat folgendes geschrieben: | Hallo DevilFish,
warum machst Du es nicht einfach mit Schiebeoperationen |
Entweder willst du mich veräppeln oder ich bin tatsächlich nicht der Einzige, der's überlesen hat. 
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 16.09.08 11:42
Auch wenn das Problem bereits gelöst wurde. Eine Schleife mit einer konstanten Anzahl an durchlaufen ist der Overkill. Die sollte man durch das Wiederholen des Codes ausrollen. Die Schiebeopratoren sind gut. Allerdings sollte man dann auch die Addition bzw das Inc (was auch zur addition wird) sein lassen. Dazu kann man auch den Operator OR benutzen. Denn der fügt nur unterschiedliche Inhalte zusammen und das ist im Endeffekt das Gleiche, nur ohne mathematische Operationen. Allerdings kann man dort auch mit Assembler arbeiten, dann würde man durch die Benutzung der Register AL und AH lediglich noch ein einziges Schieben benötigen und hätte sonst nur simple Zuweisungen ganz ohne irgendwelche Operationen.
Allerdings ist selbst die Variante in Assembler mit Aufwand verbunden. Und sei es nur der Aufwand eine Methode aufzurufen (der häufig einfach ignoriert wird). Aufwand der eigentlich dadurch umgangen werden kann in dem man dafür sorgt, dass die einzelnen Variablen sich einen Speicherbereich teilen. Denn dann muss man nur entscheiden wie man drauf zugreifen möchte. Und diese Möglichkeit hatte Narses bereits gezeigt. Ich denke etwas schnelleres wird es nicht geben. Das case in dem Record ist im übrigen nicht nur auf 2 Einträge beschränkt. Man kann auch auch ein case für 2 Words einfügen etc. Oder was man halt sonst noch benötigt.
Eine andere Alternative zu Speicherteilen ist der Operator absolute. Damit teilt man dem Kompiler mit, dass die Speicherstelle an der Adresse der Anderen liegt. Allerdings wenn man sich mit der Zielvariable vertut, dann kann man sich ziemlich schnell irgendwas kaput machen. Also lieber die Recordvariante auch wenn die mehr Schreibarbeit bedeutet.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 16.09.08 12:05
Moin!
Lossy eX hat folgendes geschrieben: | Allerdings ist selbst die Variante in Assembler mit Aufwand verbunden. |
Ich hätte da nochmal eine Frage zum byte-sex der CPUs, ist ja die richtige Sparte hier und leidlich ins Thema passen tut´s auch.
Ich habe mir von Leuten, die es wissen sollten, sagen lassen, dass man bei "modernen" CPUs (also damals...  es ging um Intel x86 und PowerPC) den byte-sex im Steuerregister umschalten kann!  Man könnte also theoretisch vor einer Lese-Operation von big- auf little-endian switchen und dann wieder zurück, analog beim Schreiben.
Geht das? Wenn ja, wie?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Di 16.09.08 12:53
Ich muss gestehen da haste mich jetzt ein bisschen eiskalt erwischt.  Ohne mein schlaues Buch weiß ich kaum etwas. Und das liegt zu Hause.
Ob es ein Flag gibt, was das automatisiert steuert, weiß ich nicht. Allerdings gibt es den Befehl BSWAP. Der tauscht in einem Rutsch in einem 32 Bit Register die Bytes 1 mit 4 und 2 mit 3. Also dreht genau die Reihenfolge der Bytes um.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 16.09.08 13:46
Narses hat folgendes geschrieben: | Aber Vorsicht! Intels sind big-endian CPUs! Die Werte sind also genau andersrum in Speicher, als beim binären Zahlensystem, Motorola-CPUs, Network-Byte-Order und wie von dir erwartet.
cu
Narses |
Also Narses!!! Intel's sind die TYPISCHEN Vertreter für Little Endian!
Big-Endian sind z.B. die ganzen Sun-Kisten, die Java-VM, die ganzen Motorola-Prozessoren (der 68k z.B.) und die gesamte Übertragung im Netzwerk (Network Order), was auch von den ganzen Sun-Mainframes herrührt, die dominant waren, als die ganzen RFCs entwickelt wurden.
Und ein Zahlensystem an sich kann nicht Little-Endian oder Big-Endian per se sein. Ich kann auch
11111110bLE schreiben und habe damitim Binärzahlensystem Little-Endian genutzt. Was du sicherlich meintest war, dass man auf dem Papier typischerweise Big Endian verwendet, da dieses einfach gewohnt für uns ist.
@Narses: k, fühlt sich gut an, das auch mal bei Dir zu machen, wenn Du das sonst immer in meinem TuDorial machst 
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 16.09.08 14:17
Moin!
BenBE hat folgendes geschrieben: | Also Narses!!! Intel's sind die TYPISCHEN Vertreter für Little Endian!  |
Jaja, hast ja recht  hab´s mal wieder verwechselt...  Hätte mal direkt hier reinsehen sollen... *seufz*
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
DevilFish 
Hält's aus hier
Beiträge: 13
|
Verfasst: Di 16.09.08 21:25
Danke für die vielen Antworten.
Ich werd mal Narses Ansatz probieren. Leider zieht diese Methode noch gravierende Änderungen der Proceduren zum lesen/schreiben und ver- und entschlüsseln nach sich, da ich 2048 Byte auf einmal einlese und unnötige weitere herumschieberei der Daten verhindern möchte.
Hab mir das so gedacht: Buffer : array[1..512] of T4Byte;
Und damit dann 2048 Blöcke auslesen.
@baka0815: Ja das b steht da falsch, ist im Original aber alles am rechten Fleck.
Ist wohl bei copy/paste und schnell was ändern und dazuschreiben was falsch
gelaufen.
mfg DevilFish
--- Moderiert von Narses: Beiträge zusammengefasst---
Und verdammte Axt, es geht alles auf anhieb.
vielen Dank Narses. 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 16.09.08 22:34
Moin!
Bitte, gern geschehen.
Markierst du den Thread noch entsprechend, wenn dein Problem gelöst ist? Danke.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Greenberet
      
Beiträge: 339
Erhaltene Danke: 20
Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
|
Verfasst: Mi 17.09.08 07:55
|
|