Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - zwei Zeichen per XoR miteinander verknüpfen
Bomania - So 16.02.03 11:04
Titel: zwei Zeichen per XoR miteinander verknüpfen
Hallo,
ich möchte zwei Zeichen per XoR miteinander verknüpfen und das Ergebnis als ASCII-Zeichen ausgeben. So wie hier funktioniert es einwandfrei:
Quelltext
1:
| chr(ord('D') xor ord('t')); //Ergebnis = 0 (#48) |
Wenn es sich jetzt aber um String-Variablen handelt, weil ich mehrere Zeichen nacheinander miteinander verknüpfen möchte, dann funktioniert die Sache nicht:
Quelltext
1: 2: 3:
| // str1 = 'Hallo', str2 = 'Test' // per For-Schleife wird jeweils um eine Position in i und i2 weitergegangen chr(ord(str1[i]) xor ord(str2[i2])); |
Dann habe ich es so versucht:
Quelltext
1:
| chr(ord(copy(str2,i,1) xor ord(copy(str1,ipos,1))); |
Hier erscheint die Fehlermeldung "Inkompatible Typen"
Ich weiß langsam echt nicht mehr weiter. Was unter VB mit 10Min Aufwand funktioniert hat, kriege ich unter Delphi nicht mal in 2 Tagen hin. Dabei ist Delphi doch eigentlich in vielen Dingen leichter zu handhaben als mit anderen PS.
Kann mir da jemand helfen? Was habe ich oben falsch gemacht? :(
Moderiert von
Tino: Titel geändert.
BungeeBug - So 16.02.03 11:10
darf man fragen was du vor hast?
MfG BungeeBug
Bomania - So 16.02.03 11:26
Das habe ich oben ja bereits versucht zu erklären. Aber ich versuche es nochmal deutlicher zu beschreiben.
Ich habe zwei Variablen:
str1 := 'Hallo';
str2 := 'Text der mit str2 vernüpft werden soll';
Diese möchte ich per XoR verknüpfen (hier im Pseudocode):
'T' XoR 'H' (= irgendein anderes Zeichen)
'e' XoR 'a' (= irgendein anderes Zeichen)
usw...
Ist das Ende von str1 erreicht, fängt es wieder von vorne an (also 'H'). Auf diese weise möchte ich einen kompletten Text der in str2 gespeichert ist mit str1 verknüpfen. Das geschieht mit einer For-do-Schleife.
Um das nochmal praktisch zu zeigen, hier die entsprechende Stelle:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| intStr1Len := Length(str1); ipos := 1; For i := 1 To Length(str2) do begin If ipos > intStr1Len Then begin ipos := 1; end; //if
txt_Text.text:=txt_Text.text + chr(ord(str2[i]) xor ord(str1[ipos])); ipos := ipos + 1; end; //for |
Edit: Als Ergebnis sollte dann ein Text herauskommen, der genausoviele Zeichen hat wie str2. Das ist aber nicht der Fall. Irgendwie ist da der Wurm drin.
Edit2: Ich habe es nochmal überprüft - die XoR-Verknüpfung funktioniert. Das Problem liegt an der Chr()-Funktion. Als Ergebnis bekomme ich bis auf das erste Zeichen nur schwarze Blöcke.
Bomania - So 16.02.03 14:04
Titel: Problem liegt wo ganz anders
Das gibts ja nicht, das Problem liegt wo ganz anders. Nach ewigen Tests habe ich heraus gefunden, dass die Schleife wohl abbricht, sobald zufällig ein Zeichen von str1 auf ein identisches Zeichen von str2 'trifft' (z.B. 't' auf 't'). Das kann ich mir nun wirklich nicht erklären. Habt ihr ne Idee?
DaRkFiRe - So 16.02.03 14:34
t XOR t = 0
t XOR 0 = t
0 XOR t = t
0 XOR 0 = 0
nehmt das t jetzt bitte mal als Buchstabe, der gedanklich in einen ASCII-Code übersetzt wird
Und wie wir alle wissen, wird ein Speicherstring (ein PChar) mit einem #0 terminiert, soweit nicht anders vereinbart (GetMem, z.B.)
Sollte es eine Verschlüsselungsprozedur werden, rate ich zu folgendem Code:
es sei S1 der Ursprungs-String, S2 das "Passwort"
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var S1,S2,S3:STRING; var I:INTEGER; ... S3:=STRINGOFCHAR(#0,LENGTH(S1)); for I:=1 TO LENGTH(S1) do begin S3[I]:=BYTE(S1[i]) XOR BYTE(S2[((I-1) MOD LENGTH(S2))+1]); end;
//das Ergebnis ist in S3 |
Bomania - So 16.02.03 14:51
Quelltext
1:
| S3[I]:=BYTE(S1) XOR BYTE(S2[((I-1) MOD LENGTH(S2))+1]); |
In dieser Zeile bekomme ich eine Fehlermeldung "Ungültige Typumwandlung" und eine Warnung "Vorzeichenbehaftete und -lose Typen werden kombiniert"
DaRkFiRe - So 16.02.03 15:39
Quelltext
1:
| S3[I]:=BYTE(S1[i]) XOR BYTE(S2[((I-1) MOD LENGTH(S2))+1]); |
Aufmerksame im-Kopf-vor-Kompilierer haben es sicher schon gemerkt:
S3[I] ist vom Typ char
Richtig müsste es ungefähr so gehen:
Quelltext
1:
| S3[I]:=CHR(BYTE(S1[i]) XOR BYTE(S2[((I-1) MOD LENGTH(S2))+1])); |
Brueggendiek - Mo 17.02.03 03:17
Titel: Re: zwei Zeichen per XoR miteinander verknüpfen
Hallo!
So
| Bomania hat folgendes geschrieben: |
Quelltext 1:
| chr(ord(copy(str2,i,1) xor ord(copy(str1,ipos,1))); |
Hier erscheint die Fehlermeldung "Inkompatible Typen"
|
kann das ja nicht gehen! Copy(quelle, start, laenge) ist ein String, Ord erwartet ein Zeichen!
Innerhalb der Länge der Strings (WICHTIG!) muß man schreiben:
Quelltext
1:
| chr(ord(str2[i]) xor ord(str1[ipos])); |
dann geht das!
Es muß nur sichergestellt sein, daß i und ipos nicht kleiner als 1 und nicht größer als die Länge des Strings sind!
Gruß
Dietmar Brüggendiek
BungeeBug - Mo 17.02.03 13:44
Titel: Re: Problem liegt wo ganz anders
| Bomania hat folgendes geschrieben: |
| Das gibts ja nicht, das Problem liegt wo ganz anders. Nach ewigen Tests habe ich heraus gefunden, dass die Schleife wohl abbricht, sobald zufällig ein Zeichen von str1 auf ein identisches Zeichen von str2 'trifft' (z.B. 't' auf 't'). Das kann ich mir nun wirklich nicht erklären. Habt ihr ne Idee? |
Ja kann ich das "XOR" is das "exclusive OR" was soviel heisst wie ausschliesendes oder
Quelltext
1: 2: 3: 4: 5: 6:
| a | b | c | ------------ 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | |
also das "wirkt" nur wenn die beiden Variablen verschieden sind ...
das was du warscheinlich suchst is das normale "OR"
Quelltext
1: 2: 3: 4: 5: 6:
| a | b | c | ------------- 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | |
P.S.: A = Eingang 1 also ne Variable
B = Eingang 2 also auch ne Variable
C = Ausgang 1 also on jetzt true oder false
MfG BungeeBug
Bomania - Fr 21.02.03 09:53
Danke für die Nachhilfe, aber die Funktionsweisen von XoR, Or und AND sind mir bereits vertraut (sonst würde ich mit diesen Verknüpfungsoperationen wahrscheinlich gar nicht arbeiten). Das Problem ist mittlerweile gefunden: das Memo ist dran schuld. Denn es terminiert bei #0. Und #0 entsteht jedesmal wenn man zwei identische Zeichen mit XoR miteinander verknüpft. Das muss man anscheinend so hinnehmen, denn das Memo zeigt den Text nur bis zum ersten #0.
HeLe - So 02.03.03 11:16
| Bomania hat folgendes geschrieben: |
| Das Problem ist mittlerweile gefunden: das Memo ist dran schuld. Denn es terminiert bei #0. Und #0 entsteht jedesmal wenn man zwei identische Zeichen mit XoR miteinander verknüpft. Das muss man anscheinend so hinnehmen, denn das Memo zeigt den Text nur bis zum ersten #0. |
Das Memofeld ist nicht daran schuld, das ist ganz einfach eine Eigenschaft von
nullterminierten Strings wie sie Delphi (und auch C/C++) benutzt. Das Ende eines solchen Strings wird eben durch das Nullzeichen angezeigt - das ist halt so. Das alte Pascal (und anscheinend auch VB - aber damit kenn ich mich nicht aus) benutzt ne andere Technik: Da wird im 1. Byte die Länge des Strings gespeichert, mit dem Effekt, das so ein String nur 255 Zeichen enthalten kann. Deswegen - und um kompatibel zu C-Funktionen (wie z.B. die aus der Windows-API) zu werden - sollten diese Strings in Delphi nicht mehr verwendet werden, du kannst sie aber noch benutzen wenn du den Datentyp
shortstring verwendest (damit kommen dann allerdings die Komponenten nicht klar, weswegen dir das wohl wenig helfen wird)
DaRkFiRe - So 02.03.03 14:39
Hallo HeLe!
Du bist aber ganz dolle im Irrtum, ganz ganz dolle.
Denn Memo is nix weiter als ein vordefiniertes Windows-Control (Delphi kapselt nur die Messages an das Fenster) und da Windows intern mit Zeigern arbeitet (wer tut das nicht!?), ist, wenn man einen Zeiger übergibt, bei #0 Schluss.
Weise bitte mal einem String (AnsiString - also als STRING deklariert) folgendes zu (Du deklarierst ihn mal als globale Variable):
Quelltext
1:
| S:=STRINGOFCHAR(#0,7); |
Dann gib den String mal im Formular-Titel (Caption) aus (meinetwegen in OnCreate):
Er zeigt nichts an! Warum??? WINDOWS arbeitet intern mit Zeigern, die bei #0 terminieren.
Jetzt gib doch mal an ihrendeiner Stelle im Programm die Länge des Strings aus - es wird 7 sein, Delphi (hoho!?) terminiert INTERN nicht bei #0!!!
Womit nicht Delphi, sondern Windows daran schuld ist.
Alle Klarheiten beseitigt!?
HeLe - So 02.03.03 17:16
s.u.
HeLe - So 02.03.03 17:28
oops, stimmt :oops: , dann speichert Delphi bei ansistrings doch die Länge. Naja, das nützt einem auf jeden Fall nicht viel, da man bei der Ausgabe normalerweise um die Windows-API nicht drumrumkommt.
Es ist aber kein "Fehler", da die Windows-API-Funktionen in C programmiert sind, das ist eigentlich alles was ich sagen wollte. :lol:
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!