Vigenere Ver- Entschlüsselung in C
-
Hi,
Meine Aufgabe ist es ein Programm zu schreiben welches den Benutzer auffordert als erstes zu Fragen ob er eine Ver- oder eine Entschlüsselung durchgeführt haben möchte.
Nachdem Ver bzw. Entschlüsseln ausgewählt wurde soll der Benutzer den Klartext bzw den Geheimtext eingeben mit dem jeweiligen Schlüssel.
Ausgeben soll selbstverständlich entweder der Klartext oder der Geheimtext je nach Option welche am Anfang gewählt wurde.
(Die Eingabe wird in Großbuchstaben eingeben)Meine Verschlüsselung habe ich bereits fertig hier mein Code:
# include <stdio.h>
# include <conio.h>
# include <ctype.h>
# include <string.h>void vigenere(char *text, char *schluessel){
unsigned int i, j;
printf("Geheimtext : ");
for(i=0,j=0;i<strlen(text);i++, j++)
{
if(j>=strlen(schluessel))
{
j = 0;
}if(text[i] >= 'A' && text[i] <= 'Z')
{printf("%c",65+(((toupper(text[i])-65)+(toupper(schluessel[j])-65))%26));
}else if(text[i] >= 'A' && text[i] <= 'Z')
{
printf("%c",65+(((toupper(text[i])-65)+(toupper(schluessel[j])-65))%26));
}}
}int main(){
char text[100], schluesselwort[100];
printf("Klartext : ");
gets(text);
printf("Schluessel : ");
gets(schluesselwort);
vigenere(text, schluesselwort);
getch();}
Meine Fragen dazu:
-wo baue ich am besten den switch für die cases ein ?Außerdem weiß ich nicht genau wie der Code für die Entschlüsselung aussehen soll
Ich hoffe ihr könnt mir weiterhelfen
Gruß
-
Vigenere schrieb:
Meine Fragen dazu:
-wo baue ich am besten den switch für die cases ein ?Wieviel Möglichkeiten hast du denn?
Du hast ja nur drei Funktionen:main
, verschlüsseln und und entschlüsseln.Vigenere schrieb:
Außerdem weiß ich nicht genau wie der Code für die Entschlüsselung aussehen soll
Verschlüsseln ist Text + Code
Entschlüsseln ist Geheimtext - CodeDeine Funktionen sollten den ver- bzw. entschlüsselten Text zurückgeben, nicht ausgeben.
Die Ausgabe kann dann in main erfolgen.
Du benutzt Magic Numbers. 'A' und 65 ist in C (bei ASCII) identisch.Wenn du schon
ctype
nimmst, dann kannst du auch beim Vergleich auchisupper
nehmen.
'Aber warum überhaupt der Vergleich auf Großbuchstaben?
Du wandelst danach ja sowieso in Großschreibung um.
Sonderzeichen unterschlägst du komplett.
Dein else-Zweig ist identisch mit dem if-Zweig.Die Funktion
gets
geht gar nicht. Nie benutzen. (Außer bei Demonstrationen von Pufferüberläufen).Nutze bitte beim nächsten mal Code-Tags, dann bleibt die Formatierung erhalten.
Ob das klappt, kannst du mit der Vorschau sehen.geheim[i] = 'A'+(((toupper(text[i])-'A')+(toupper(schluessel[j])-'A'))%('Z'-'A'+1));
-
Bau doch on case ein. Hier zum schmökern ein alter code von mir, ist zwar mit goto aber zumgucken reicht es.
/* enig_a.c ist ein einfaches Programm zum kodieren und dekodieren von Dateien Dieses Beispiel dient zur Demonstration von Schreib- und Lesezugriffen */ #include <stdio.h> //getch #include <stdlib.h> /* für malloc */ #include <fcntl.h> // wegen open #include "direct.h" /* Symbolische Konstanten für open */ #include <errno.h> // wegen errno #include <unistd.h> // wegen close, lseek, getch #include <termios.h> // getch /* Ersatz für das im DOS übliche getch, funzt auch auf der Linux-Konsole */ int getch(){ struct termios oldt, newt; int ch; tcgetattr( STDIN_FILENO, &oldt ); newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); tcsetattr( STDIN_FILENO, TCSANOW, &newt ); ch = getchar(); tcsetattr( STDIN_FILENO, TCSANOW, &oldt ); return ch; } // Zeigt das Schlüsselwort an void SLUAN(unsigned char schluessel[], int *codelaenge) { int sleia; printf("\nSchüsselwort:\n"); for (sleia = 0; sleia <= 99; sleia++) {// Das Zeichen für Stringende ist Null printf("%c", schluessel[sleia]); if (schluessel[sleia] == 0) { *codelaenge = sleia; goto finito; } } finito: printf("\n"); } /* Bestimmt die Länge einer Datei, diese wird als long zurückgegeben */ long getdatlen(char datname[]) { int fh; long rewer = 0L; if( (fh = open( datname, _O_RDONLY | _O_BINARY ) ) == -1 ) { rewer = errno; goto finito; } rewer = lseek(fh, 0, SEEK_END); close( fh ); finito: return(rewer); } // Löscht den Tastaturspeicher, um fehlerhafte Eingaben zu vermeiden void clpuf(void) { while (getchar() != '\n') ; } void getfilename(char *text, char dateiname[]) { printf("%s", text); scanf("%s", dateiname); } int main(void) { int codze, codelaenge, wohin = 0, zeichen, kodierart = 0; char queldat[70], zieldat[70]; unsigned char schluessel[100], dummy; long slei, groesse; FILE *fziel, *fquelle; printf("\nCodierungsprogramm Wiscod V0.1"); hauptmenue: printf("\n\nSchlüssellänge maximal 90 Zeichen!"); printf("\nSchlüssel eingeben............1"); printf("\nSchlüssel anzeigen............2"); printf("\ncodieren......................3"); printf("\ndecodieren....................4"); printf("\nEnde..........................0"); printf("\n\nIhre Wahl: "); wouhi: scanf("%d", &wohin); clpuf(); if (wohin == 1) goto schluessel; if (wohin == 2) goto schlissl; if (wohin == 3) { kodierart = 0; goto danafa; } // 0 = kodieren if (wohin == 4) { kodierart = 1; goto danafa; } // 1 = dekodieren if (wohin == 0) goto finito; goto wouhi; dateilesen: printf("\n\nDatei öffnen..1 Zurück..0"); printf("\n\nIhre Wahl: "); scanf("%d", &wohin); if (wohin == 0) goto hauptmenue; if (wohin == 1) goto danafa; goto dateilesen; danafa: getfilename("\nName der Quelldatei: ", queldat); getfilename("\nName der Zieldatei.: ", zieldat); //Zuerst Länge der Quelldatei bestimmen groesse = 0; printf("\nDateigröße wird ermittelt."); groesse = getdatlen(queldat); if (groesse == -1) { printf("Fehler beim Öffnen der Quelldatei."); goto dateilesen; } printf("Die Dateigröße der Quelldatei beträgt: %ld Zeichen", groesse); // Lese Quelldatei im Binärnmodus (b) ein, fquelle = fopen(queldat, "rb"); if (fquelle == NULL) { printf("\nEine Öffnung der Quelldatei ist nicht möglich."); goto dateilesen; } printf("\nDie Quelldatei wurde geöffnet.\n"); fziel = fopen(zieldat, "wb"); if (fziel == NULL) { printf("\nEine Erstellung der Zieldatei ist nicht möglich."); goto dateilesen; } printf("\nDie Ziel wurde Erstellt.\n"); /*Kodieren oder dekodieren der Datei n bei 0 ist kodieren angesagt */ codze = 0; if (kodierart == 0) printf("\nKodieren von %ld Zeichen", groesse); else printf("\nDekodieren von %ld Zeichen", groesse); for (slei = 0; slei < groesse; slei++) { zeichen = fgetc(fquelle); /* slei=Zeichenenmenge beim einlesen */ if (zeichen == EOF) break; // naunco = "Nachricht uncodiert" if (kodierart == 0) { dummy = (unsigned char)zeichen + schluessel[codze]; if (dummy > 255) dummy -= 255; } if (kodierart == 1) { dummy = (unsigned char)zeichen - schluessel[codze]; if (dummy < 0) dummy += 255; } fputc(dummy, fziel); codze++; if (codze >= codelaenge - 1) codze = 0; } if (kodierart == 0) printf("\nDatei wurde kodiert"); else printf("\nDatei wurde dekodiert"); fclose(fquelle); fclose(fziel); printf("\nDie Dateien wurden geschlossen."); printf("\nEs wurden %ld Zeichen bearbeitet.", slei); goto hauptmenue; /*Schlüsselwort eingeben */ schluessel: for (slei = 0; slei <= 99; slei++) schluessel[slei] = 0; printf("\nBitte Schlüsselwort eingeben: "); scanf("%[^\n]", schluessel); /* alle Zeichen, auch Leerzeichen bis auf Enter einlesen */ printf("\nIhre Eingabe:\n"); SLUAN(schluessel, &codelaenge); // Schlüsselwort anzeigen printf("\nDas Schlüsselwort ist %d Zeichen lang", codelaenge); goto hauptmenue; schlissl: printf("\nSchlüsselwort anzeigen\n"); SLUAN(schluessel, &codelaenge); goto hauptmenue; finito: printf("\nProgrammende"); return(0); }
Geschrieben habe ich damals das ganze auf codeblocks 13.12. Es ist ein
einfaches Beispiel der Substitution, quasi Ersatzalphabet. Da ich es
mit der englischen Sprache nicht so habe sind die Bezeichner etwas
schräg geraten. Rein theoretisch könnte man zuerst die Dateilänge der
zu kodierenden Datei bestimmen, dann eine Datei mit Zufallszahlen
im Zahlenbereich 0 bis 255 anlegen, deren Anzahl der Byts, also der
Zufallszahlen genau so lange ist, wie die zu verschlüsselnde Datei
selbst. Danach müßte man beide Dateien gleichzeitig öffnen und die
Kodierung durchführen. Das Ergebnis würde dann logischerweise in einer
anderen Datei abgspeichert. Der Urcode wurde von mir 1994 schon auf
Quick-c 2.5 geschrieben. Angefangen habe ich mit einem
Symantec C 6.11 Shareware-compiler, die Schnupperversion von
Symantec C 7.0. Nach meinem Umstieg auf Linux wollte ich die Codes
aller meiner Dateien auf Codedeblocks portieren. Aber was da an 20 Jahren
Hobby-programmieren zusammengekommen ist, da müßte ich 200 Jahre alt werden
um das zu schaffen. Man wird eben älter!
-
Wen interessiert dieser Müll?
Alles Schrott.
Liebe Kinder, nicht nachmachen.
-
Wenn schon Kritik, dann konstruktive und sachliche Kritik.
Wenn du in einer Firma arbeitest du hast ein brainstorming,
Kaizen (PDCA), Fishbon-Ishikawa, FMEA oder andere QM-Meetings
kannst du auch keine Killerphrasen verwenden, es sei denn, du
willst deinen Job gleich wieder an den Nagel hängen.
-
Du hast keine Ahnung von C, das hast du mehrfach bewiesen.
Dein Code ist vollkommener Schrott.
Wenn du eine Frage zu Standard C hast, stelle sie hier in qualifizierter Form.
Und unterlasse alle deine "...gut gemeint..." Ratschläge, die interessieren niemanden, sind falsch und behindern die Problemlösung durch die qualifizierten Antworter hier im Forum.
-
Sorry, das ist Schrott.
In dem Stil hat man auf dem C64 in BASIC programmiert.Wenn du den Code, nach 20 Jahren, immer noch gut findest, hast du nichts dazu gelernt.
Etwas detailierte Kritik:
- unnötige gotoscanf
mit %s oder %[ ohne length-Modifier. Da kannst du auch gets nehmen.
- unnötige goto
- viel zu kompliziert
- unnötige goto
- nichtssagende oder irreführende Funktionsnamen
- unnötige goto
- unnötige POSIX-Funktionen
- der Code geht an der gefragten Aufgabe weit vorbei
Konstruiktive Kritik:
Schmeiß den Code weg und lösch den hier.
-
Ach Wutz lass doch deine lieben, netten, konstruktiven, nutzlosen, völlig unbrauchbare Kommentare bei dir zu Hause im Bett. Dich braucht keiner wenn du nur solchen (Zitat) Müll oder Schrott schreibst, vielen Dank.
Du hast keine Ahnung von C, das hast du mehrfach bewiesen.
Dein Code ist vollkommener Schrott.
Wenn du eine Frage zu Standard C hast, stelle sie hier in qualifizierter Form.
Und unterlasse alle deine "...gut gemeint..." Ratschläge, die interessieren niemanden, sind falsch und behindern die Problemlösung durch die qualifizierten Antworter hier im Forum.Ach ja freundlic wie eh und je. <333
Ich glaube ich habe 1 unter 10 deiner Antworten (oh entschuldige, wir sagen lieber hochqualifizierte Kommentare) gesehen, die tatsächlich mal etwas zum Inhalt beigetragen haben :OO
-
TocToc schrieb:
Ach Wutz lass doch deine lieben, netten, konstruktiven, nutzlosen, völlig unbrauchbare Kommentare bei dir zu Hause im Bett. Dich braucht keiner wenn du nur solchen (Zitat) Müll oder Schrott schreibst, vielen Dank.
Wutz ist sehr oft hilfreich.
Auch daß er rustyoldguys Ergüsse aus Sicht eines Fachmanns rezensiert, ist prima.TocToc schrieb:
Ich glaube ich habe 1 unter 10 deiner Antworten (oh entschuldige, wir sagen lieber hochqualifizierte Kommentare) gesehen, die tatsächlich mal etwas zum Inhalt beigetragen haben :OO
Diese Quote sehe ich bei Dir. Also kann mich jetzt an keinen Code von Dir erinnern, nur an das fachfremde Gemecker wie schrechlich gemein die Großen sind.
-
Sweet.
Weiß nicht ob du das bis jetzt bemerkt hast, bin Anfänger. Nur mal so nebenbei..Wutz ist sehr oft hilfreich.
Ich geh mal kurz lachen. Später vllt..
Auch daß er rustyoldguys Ergüsse aus Sicht eines Fachmanns rezensiert, ist prima.
Das ist aber schon sehr schöngeredet..
-
Nur interessiert das niemanden, ob oder was du zu meinen Antworten beizutragen hast; ich kann verstehen wenn du meine Beiträge nicht verstehst, ein Mindestmaß an Auffassungsgabe und Intellekt sind dafür nämlich notwendig.
Deine eigenen "Beiträge", in denen du nur dein irgendwo aufgeschnapptes Halbwissen ohne Sinn und Verstand nachplapperst sind ebenso falsch und dilettantisch wie die von dem oben zitierten Herrn, und behindern ebenso nur eine qualifizierte Problemlösung.
Trolle dich dahin wo du hergekommen bist und halt die Klappe, wenn sich Erwachsene unterhalten.
-
TocToc schrieb:
Weiß nicht ob du das bis jetzt bemerkt hast, bin Anfänger. Nur mal so nebenbei..
Mensch, dann sei doch froh, daß es hier Leute wie Wutz gibt!
Oder willste aus Wolf-Büchern und rustyoldguys Programmen lernen?
-
#include <stdio.h> #include <string.h> #include <ctype.h> #include <conio.h> void eingabepuffer_leeren(); void vigenere(char *text, char *schluessel); void einlesen(char *text, int lenText, char *schluessel, int lenSchluessel); int main() { char auswahl; char text[100]; char schluessel[100]; do { einlesen(text, sizeof(text), schluessel, sizeof(schluessel)); printf("\n### Auswahl ###\n\n"); printf("V) Verschluesseln\n"); printf("E) Entschluessen\n"); printf("B) Beenden\n"); printf("\nAuswahl: "); scanf("%c", &auswahl); eingabepuffer_leeren(); switch (auswahl) { // Auswahl 1 bzw. 2: // Macht in diesem Fall keinen Unterschied, da Verschlüsselung und Entschlüsselung analog sind bzw. sein sollten... case 'v': case 'V': vigenere(text, schluessel); break; case 'b': case 'B': printf("Programm wird beendet.\n"); break; default: printf("Fehlerhafte Eingabe!\n"); } } while (auswahl != 'b' && auswahl != 'B'); return 0; } void eingabepuffer_leeren() { char c; while ((c= getchar()) != '\n' && c != EOF) /* verwerfen */ ; } void einlesen(char *text, int lenText, char *schluessel, int lenSchluessel) { printf("### Text/Schluessel ###\n"); printf("Text: "); fgets(text, lenText, stdin); printf("Schluessel: "); fgets(schluessel, lenSchluessel, stdin); } void vigenere(char *text, char *schluessel) { printf("Geheimtext: "); printf("<noch zu implementieren>\n"); printf("\n"); }
-
Es fehlt natürlich das case für die Entschlüsselung, denn da es ohnehin unnötig ist, hab ich es ausversehen wegoptimiert.
-
Ver- und entschlüsseln sind nicht gleich.
(könnte es, wenn der Schlüssel aus 'N' besteht)Der Prototyp sollte (IMHO) so aussehen:
void vigenere(char *geheimtext, size_t groesse_von_geheimtext, char *text, char *schluessel);
fgets lässt das '\n' im Text. Das könnte Probleme geben.
eingabepuffer_leeren() dunktioniert nur richtig, wenn c ein
int
ist.
Im übrigen ist der NAme der Funktion irreführend.Ein
auswahl = toupper(auswahl)
nach der Eingabe macht den Code auch lesbarer.
Deine Menüführung macht den User wütend.
Tipp:
Ein Leerzeichen vor dem %c beiscanf
wirkt manchmal Wunder (nicht unbedingt hier, aber es schadet nicht):scanf(" %c", &auswahl);