PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Caesar Chiffre - Problem



chilliboy999
22.11.2010, 01:12
Hey Leutz,
da ich das Programmieren in letzter Zeit leider etwas vernachlässigt habe wollte ich mal wieder iwas coden. Da bin ich zufällig auf das Thema Verschlüsselung gestoßen. Dann hab ich mir die einfachste Verschlüsselung, die Caesar Chiffre, rausgesucht die man finden kann und nun wollte ich diese im Bereich C/C++ anwenden.

Nun ergibt sich bei mir folgendes Problem: Sobald ich einen zu hohen Integerwert festlege, kommt bei der Entschlüsselung teilweise "Crap" raus...
Ich habe folgendes Beispiel ausgewählt: Text: TopSecretTextVeryDangerous ; Integerwert: 9

Wisst ihr vllt. woran es liegen könnte?



#include <iostream>
#include <string>

using namespace std;

int main()
{
char Alpha[53] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx yz";

cout << "Bitte geben Sie einen Text ein, welcher verschluesselt werden soll:\n";
char text[2048]; //255
cin >> text;
cout << "Bitte geben Sie ihren persoenlichen Verschluesselungs-Integerwert ein: ";
int ver;
cin >> ver;
int length;
length = strlen(text);

int enci;
int enca;
for (enci=0; enci<length; enci++)
{
int j;
for (j=0; j<55; j++)
{
if(text[enci] == Alpha[j])
{
enca = j;
j=100;
}
else
{}
}

enca = enca + ver;

if(enca>53)
{
enca = ver-1;
}

text[enci] = Alpha[enca];
}

cout << "Der verschluesselte Text lautet nun: " << text << endl;

int deci;
int deca;
for (deci=0; deci<length; deci++)
{
int j;
for (j=0; j<55; j++)
{
if(text[deci] == Alpha[j])
{
deca = j;
j=100;
}
else
{}
}
deca = deca-ver;

if(deca<0)
{
deca = 53 - (ver-1);
}

text[deci] = Alpha[deca];
}

cout << "Entschluesselung: " << text << endl;

system("pause");
return 0;
}

j0kR
22.11.2010, 02:47
Also das ist mein Quellcode für das Caesar-Verfahren mit A=K


byte[] ascii = Encoding.ASCII.GetBytes(textBox1.Text); //jedes Zeichen wird in einem Array gespeichert und als ASCII-Values ausgegeben

for (int i = 0; i < textBox1.Text.Length; i++) //Schleife die alle ASCII-Values so ändert, dass gilt A=K und a=k
{
if (ascii[i] < 91) //Überprüfung ob es sich um große oder kleine Buchstaben handelt <91 = große B. >91 = kleine B.
{
if (ascii[i] > 80) //Bei Werten über 80 würden keine Buchstaben entstehen deswegen..
{
ascii[i] -= 16; //+ 10 - 90 + 64 => -16 => ergibt für den Wert 81 Q also A
}
else
{
ascii[i] += 10; //Erhöhung um 10 entspricht A=K
}
}
else
{
if (ascii[i] > 112) //Würde keine kleinen Buchstaben ergeben, deswegen wie oben
{
ascii[i] -= 16;
}
else
{
ascii[i] += 10;
}
}

if (ascii[i] < 50) //umgewandelte Leerzeichen werden zurückgewandelt
{
ascii[i] = 32;
}
}

for (int i = 0; i < textBox1.Text.Length; i++) //Ausgabe aller veränderten ASCII-Values (Unwandlung in bekannte Stringzeichen)
{
textBox2.Text += Convert.ToChar(ascii[i]);
}


Ich habe es kommentiert.. auch wenn es C# ist, solltest du damit erkennen, wo das Problem liegt. Ansonsten helfe ich dir gerne nochmal..

big earl
22.11.2010, 03:11
Rechts der Originaltext, daneben der ASCII Wert, daneben der veränderte Text und daneben der veränderte ASCII Wert:

ASCII Wert +1:
http://img5.imagebanana.com/img/ly00xm7q/1.png

ASCII Wert +10:
http://img5.imagebanana.com/img/96v6iw1b/2.png

ASCII Wert +100:
http://img5.imagebanana.com/img/2eh9q456/3.png

C Code:

#include <stdio.h>
#include <string.h>

int main() {
char text[1024] = "Hello world";
int s = 10;
int i = 0;
printf("Integer Wert: %i\nAlt\tASCII\t\tNeu\tASCII\n",s);
for( i; i < strlen(text); i++ ) {
printf("%c\t%i\t\t%c\t%i\n",text[i],(int)text[i],(char)text[i]+s,(int)text[i]+s );
}
return 0;
}

Denn i-wann ist auch mal die ASCII Tabelle zu ende ( ^ -^)

Du könntest dieses Problem lösen, indem du ab einem ASCII Wert von 126 wieder bei 33 beginnst zu zählen

edit:

@j0kR: nur weil sich der erste Buchstabe der beiden Programmiersprachen ähnelt, heißt das nicht, dass sie etwas gemeinsam hätten

j0kR
22.11.2010, 04:15
Hast du schon mal C und C# verglichen?
Google könnte dir dabei auch helfen..
OOP.. Syntax.. und und und..

novaire
22.11.2010, 04:53
Ok da ich ein Java Futzie bin, fang ich gar nicht erst an hier einen Source bereitzustellen, da sich ja keine Sprache ähnelt und so.

Da die Imaginären Ironie Tags jetzt geschlossen sind fang ich mal an. Warum wendest du nicht die normale Caesar-Chiffre auf deinen Text an und konvertierst dann? Ausserdem hat dein "Algo" nichts mit dem historischen Caesar Algo zu tun, soweit ich das überflogen habe.

Falls Bedarf besteht, kann ich dir eine Java Lösung zusenden ô.ô Musst du halt entscheiden.

chilliboy999
22.11.2010, 12:12
Sow, also eigtl müsste mein Code einwandfrei funktionieren. Ich hab alles logisch durchdacht, aber iwie funktioniert das nicht, wenn der Integerwert zu groß ist.

Atbash
22.11.2010, 13:11
Wieso reservierst du für Alpha 53 Bytes, wenn du doch nur 52 Zeichen hast? Für den Fall, dass das 53te Byte für das Nullbyte ist, glaube ich ist das ein Denkfehler. Meines Wissens nach brauchst du das nicht.

inout
22.11.2010, 13:22
Du könntest auch einfach isalpha bzw. isspace benutzen.
Zudem kannst du eine Schleife mit break; abbrechen, dafür brauchst du den Schleifenzähler nicht zu verändern.
Wenn du etwas Nullterminieren möchtest, dann eher den text.
Eventuell solltest du diesen Code auch mal in einer Sprache mit eingebauter Bereichsprüfung schreiben.

big earl
22.11.2010, 15:31
Sow, also eigtl müsste mein Code einwandfrei funktionieren. Ich hab alles logisch durchdacht, aber iwie funktioniert das nicht, wenn der Integerwert zu groß ist.

Wie bereits geschrieben, i-wann ist die ASCII Tabelle auch zu ende

Sollte der integer Wert die 126 übersteigen, musst du ab 33 wieder beginnen zu zählen, damit du wieder vernünftige Zeichen hast

Hier ein Beispielcode in C++:

#include <iostream>
#include <string>

int main() {
int len,i;
std::string Text,Output;

std::cout << "Text eingeben:\t";
std::cin >> Text;
std::cout << "Integer Wert:\t";
std::cin >> len;

for ( i=0; i < Text.length(); i++ ) {
if ( int(Text[i]) + len < 127 ) {
Output += int(Text[i]) + len;
} else if ( int(Text[i]) + len > 126 ) {
Output += char((int(Text[i])+len) - 126 + 32);
}
}

std::cout << Output << std::endl;
return 0;
}

Gib als Test "}" und "~" ein und Addiere sie mit 1

motion
22.11.2010, 19:17
Das Caesar-Chiffre ist nicht einfach nur die Verschiebung, sondern auch, dass das Ergebnis im "Buchstabenbereich" bleibt, Original wurde es auf einer Scheibe mit den Buchstaben ringförmig angeordnet angewendet (echtes Alphabet daneben) und sobald verrückte unleserliche Zeichen rauskommen, kann schonmal etwas nicht stimmen...

novaire
22.11.2010, 19:22
Wie ich bereits sagte, vorher anwenden, hinterher umwandeln ô.ô

Wären doch dann zwei voneinander halbwegs getrennte funktionen ..

B4n4n4
22.11.2010, 22:57
Ausserdem sollten bei der Caesar-Chiffre Zeichen mit dem schönen ASCII Wert 32 nicht mit verschlüsselt werden ;)