Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Benötige Hilfe bei Übersetzung aus D nach Object Pascal
derDoc - So 28.02.10 13:23
Titel: Benötige Hilfe bei Übersetzung aus D nach Object Pascal
Ich habe hier ein kleines Problem eine Routine (in D geschrieben) in Delphi umzusetzen.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| static void endecrypt(void[] buffer) { ushort* buf = cast(ushort *) buffer.ptr; int x=0xA2C2A; short y=0; for(int i=0; i<buffer.length>>1; i++) { x=x*0x343FD + 0x269EC3; y=x>>16 & 0x7FFF; buf[i] ^= y; } } |
Mein zentrales Problem dabei sind die Typen. Insbesondere der Buffer als dynamisches void-Array und die Benutzung des Zwischenbuffers
buf. Das Problem dabei ist, dass ich eigentlich ein Byte-Array übergebe, aber mit der Routine oben jeweils zwei Bytes ver-/entschlüssele.
Ich habe das jetzt so gelöst, bin aber nicht so glücklich damit. Eigentlich will ich wieder ein Byte-Array übergeben und nicht erst daraus ein Word-Array machen müssen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure EnDecrypt(var Buffer: array of Word); var x: Integer; y: SmallInt; i: Integer; begin x := $A2C2A; for i := 0 to High(Buffer) do begin x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; Buffer[i] := Buffer[i] xor y; end; end; |
Vielleicht hat hier ja jemand die passende Idee.
Narses - So 28.02.10 13:55
Moin!
Meinst du sowas? :nixweiss:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure EnDecrypt(var Buffer; const Size: Cardinal); var x: Longword; y: Word; i: Integer; begin x := $A2C2A; for i := 0 to Size shr 1 do begin x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; TWordArray(Buffer)[i] := TWordArray(Buffer)[i] xor y; end; end; |
cu
Narses
Horst_H - So 28.02.10 14:30
Hallo,
warum macht Dir das ein Problem?
Es steht doch auch genauso im D-Text:
C#-Quelltext
1: 2: 3:
| ushort* buf = cast(ushort *) buffer.ptr; for(int i=0; i<buffer.length>>1; i++) |
Wie Narses es jetzt zeigt...
Aber Narses hat keinen Typ angegeben.Du gehtst ja von einem "array of byte" aus.
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: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| procedure EnDecrypt(var Buffer: array of Byte); var x: Longword; y: Word; i: Integer; begin x := $A2C2A; for i := 0 to High(Buffer) shr 1 do begin x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; TWordArray(Buffer)[i] := TWordArray(Buffer)[i] xor y; end; end; procedure EnDecryptII(var Buffer: array of Byte); var x: Longword; y: Word; pWord : ^Word; i: Integer; begin x := $38414245; y := $3841; i := length(Buffer); IF i > 1 then begin pWord := @Buffer[0]; repeat pWord^ := pWord^ xor y; inc(pWord);
x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; dec(i,2); until i<=1; end; IF i = 1 then begin end; end; |
Narses - So 28.02.10 14:47
Moin!
Horst_H hat folgendes geschrieben : |
Wie Narses es jetzt zeigt...
Aber Narses hat keinen Typ angegeben. Du gehtst ja von einem "array of byte" aus. |
Der Vorteil von einem typenlosen Parameter ist, dass man der Prozedur ein beliebiges Stück Speicher hinwerfen kann. Bei der typisierten Variante ist man aber leider festgelegt. ;)
cu
Narses
Horst_H - So 28.02.10 14:59
Hallo,
dann muss man natürlich beim Aufruf aufpassen.
Denn so wäre ein Aufruf mit EnDecrypt(TestFeld,length(TestFeld)) fatal, oder nicht, oder wohl, oder doch?.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure EnDecrypt(var Buffer; const Size: Cardinal); .. var TestFeld = array of byte;
Begin ... if length(TestFeld)>0 then EnDecrypt(TestFeld[0],length(TestFeld)); .... end. |
Gruß Horst
Narses - So 28.02.10 15:18
Moin!
Horst_H hat folgendes geschrieben : |
dann muss man natürlich beim Aufruf aufpassen. |
Selbstverständlich, aber das muss man immer (ebenso wie man hier keine Blöcke mit Länge 0 übergeben sollte). ;) Es entspricht auch eher der D-Version. :nixweiss:
cu
Narses
derDoc - Mo 01.03.10 22:55
Danke ihr beiden. Das hat mir doch schon sehr geholfen. Im Übrigen dürfte der Algorithmus auch mit einer ungeraden Anzahl Bytes kein Problem haben.
Horst_H - Di 02.03.10 10:42
Hallo,
es geht nicht um das Problem, einer ungeraden Zahl und das die Verschlüsselung funktioniert, sondern das Du auf Daten zugreifst und diese veränderst, die nicht zu deinem Bytearray gehören, weil sie schon dahinter liegen.
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: 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: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107:
| {$APPTYPE CONSOLE} const MAXCNT = 1;
type TByteBuffer = array[1..MAXCNT] of byte; TTestRec = packed record Buffer : TByteBuffer; TestTheRest : byte; end; var TestRec : TTestRec;
procedure EnDecrypt(var Buffer: TByteBuffer); var x: Longword; y: Word; pWord : ^Word; pByte : ^Byte; i: Integer; begin x := $38414245; y := $3841; i := High(Buffer)-Low(Buffer)+1; IF i > 1 then begin pWord := @Buffer[Low(TByteBuffer)]; repeat pWord^ := pWord^ xor y; inc(pWord); x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; dec(i,2); until i<=1; end; IF i = 1 then begin pByte := @pWord^; pByte^:= pByte^ xor y; end; end;
procedure EnDecryptII(var Buffer: TByteBuffer); var x: Longword; y: Word; pWord : ^Word; pByte : ^Byte; i: Integer; begin x := $38414245; y := $3841; i := High(Buffer)-Low(Buffer)+1; IF i > 0 then begin pWord := @Buffer[Low(TByteBuffer)]; repeat pWord^ := pWord^ xor y; inc(pWord); x := x * $343FD + $269EC3; y := (x shr 16) and $7FFF; dec(i,2); until i<=0; end; end;
Begin writeln(' Ohne Zugriff hinter Buffer '); with Testrec do begin TestTheRest := $FF; writeln(Buffer[low(Buffer)]:5,TestTheRest:5); EnDecrypt(Buffer); writeln(Buffer[low(Buffer)]:5,TestTheRest:5); EnDecrypt(Buffer); writeln(Buffer[low(Buffer)]:5,TestTheRest:5); end; writeln; writeln(' Mit Zugriff hinter Buffer '); with Testrec do begin TestTheRest := $FF; writeln(Buffer[low(Buffer)]:5,TestTheRest:5); EnDecryptII(Buffer); writeln(Buffer[low(Buffer)]:5,TestTheRest:5); EnDecryptII(Buffer); writeln(Buffer[low(Buffer)]:5,TestTheRest:5); end; readln; end. |
Einmal wird der Wert dahinter geändert, das andere mal nicht.
Bei einem dynamschen array wird es wohl nicht auffallen, da dieses irgendwo im Speicher erzeugt wird und die Daten damit wahrscheinlich auf 4 oder 8 Byte Grenzen aligned sind und Folgedaten/Speicherreservierungen entsprechend weit weg sind, zumal sicher etwas mehr Speicher reserviert als angefordert wird.
Aber man könnte das Verfahren ja mit SSE nutzen wollen und hätte dann immer 16 Byte im Zugriff.
Aber ich will auch nicht zufällig mit dem Flugzeug abstuerzen, weil irgendwo statt 255 statt 199 steht ;-)
Gruß Horst
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!