C Programmcode Ceasar Cipher?
Hallo,
die aufgabe ist folgende:
Schreiben Sie eine Funktion, welche eine Variante des [Caesar Cipher](https://en.wikipedia.org/wiki/Caesar_cipher) auf einen String anwendet. Hierbei wird anstatt eines vorgegebenen Betrages und einer vorgegebenen Richtung für die Chiffrierung der Schlüssel für jeden Buchstaben des Klartextes neu berechnet.
Funktionsweise:
Jede Verschiebung erfolgt abhängig vom Schlüssel. Ist der Schlüssel für das aktuelle Zeichen eine gerade Zahl, so wird das aktuelle Zeichen um diesen Betrag im Alphabet nach rechts verschoben (z.B. beim Schlüssel 2 wird aus einem A ein C). Ist der Schlüssel ungerade, so erfolgt eine Verschiebung nach links (z.B. beim Schlüssel 3 wird aus einem D ein A).
Würde eine Verschiebung über das Ende des Alphabets hinaus erfolgen, so wird die Zählung bei Beginn des Alphabets fortgesetzt. Beim Schlüssel 2 wird aus einem Z also ein B bzw. beim Schlüssel 3 aus einem A ein X.
Es werden nur Buchstaben des englsichen Alphabets (A-Z und a-z) chiffriert. Alle anderen Zeichen bleiben unverändert.
Der Startschlüssel wird nur auf das erste Zeichen angewendet. Danach wird der Schlüssel nach jeder Anwendung neu berechnet, indem der Zahlenwert des zuletzt veränderten Klartext-Zeichens (also 1 für A und a, 2 für B und b, bis 26 für Z und z) durch den zuletzt verwendeten Schlüssel dividiert wird. Der neue Schlüssel für das nächste Zeichen ist der ganzzahlige Rest dieser Division. Falls es hierbei zu einer Division durch Null kommen würde (weil der zuletzt verwendete Schlüssel 0 war) wird der neue Schlüssel wieder auf den Wert des Startschlüssels gesetzt.
Folgenden Code habe ich bis jetzt geschrieben, allerdings bekomm ich bei großen Schlüsseln (zb: start_key = 100) falsche Ergebnisse raus. Weiß glaube ich auch warum: Mein Algorithmus funktioniert ja über Werteverschiebung, d.h. ab einem bestimmt großen Wert des Schlüssels verschiebt sich mein Zahlenwert des chars zu weit und dann stimmt meine "Formel" nicht mehr. Hätte es jetzt damit gelöst, dass ich zuerst mit einer if Schleife auf einen zu großen Key prüfe (zB.: if Key > 25), anschließend dividiere ich diesen Key und gehe mit dem Ergebniss in eine neue Schleife rein wobei jetzt anstatt des Keys der neue Wert addiert bzw subtrahiert wird. Anschließend durchlaufe ich diese Schleife Key%25 mal.
Aber wie setze ich das um? Zusätzlich dazu wird der Code dann mega unübersichtlich und viel zu lang für eine simple Funktion. Gibt es auch andere Möglichkeiten als meinen Code?
Ps: Ich sende den Code extra weil sonst das Zeichenlimit überschritten wird
3 Antworten
Ich würde für eine Lösung die einzelnen Schritte in einzelne Funktionen auslagern.
Zunächst gibt es zwei globale Variablen für Startschlüssel und Folgeschlüssel:
int startKey = /* some value ... */;
int key = 0;
Man könnte sie auch stets als Parameter weiterreichen, doch das erspare ich mir an dieser Stelle doch einmal.
Die erste Funktion, die benötigt wird, ist die, die den Key berechnet:
void calculateKey(char letter)
{
key = key == 0 ? startKey : (toupper(letter) - 65) % key;
key %= 26;
}
Da Groß-/Kleinschreibung beide gleich zwischen 1 und 26 laufen sollen, rechne ich alle Zeichen in Großbuchstaben um und subtrahiere dann mit 65. Erklären muss ich die Verbindung zwischen char und int ja nicht mehr, du nutzt sie genauso schon in deinem Code.
Die letzte Zeile begrenzt den Schlüssel wieder auf die 26 verfügbaren Zeichen, andernfalls kommt es bei zu großen Schlüsseln zu Überläufen.
Dann gibt es eine Funktion, die ein Zeichen verschlüsseln soll:
char encodeLetter(char letter)
{
calculateKey(letter);
int shiftDirection = (key % 2 == 0) ? key : -key;
int shifted = letter + shiftDirection;
if (letter > 96 && letter < 123) {
return getShiftedLetter(shifted, 97, 122);
}
if (letter > 64 && letter < 91) {
return getShiftedLetter(shifted, 65, 90);
}
return letter;
}
Erst wird der neue Schlüssel gebildet, dann die Verschiebung berechnet. In der darauffolgenden Abfrage wird geprüft, ob ein Groß- oder ein Kleinbuchstabe umgewandelt werden muss. Je nach Bereich wird der korrekt verschobene Buchstabe in getShiftedLetter berechnet. Die dritte mögliche Rückgabe tritt nur dann ein, wenn die zu verschlüsselnde Zeichenkette ein Zeichen enthält, welches nicht im Alphabet vorkommt.
Die letzte Funktion ermittelt den verschobenen Buchstaben:
char getShiftedLetter(int shifted, int min, int max)
{
if (shifted < min) {
return max - (min - shifted) + 1;
}
if (shifted > max) {
return min + (shifted - max) - 1;
}
return shifted;
}
Der Überlauf wird mit bedacht.
Zu guter Letzt main für einen Test:
int main()
{
int numOfLetters = 5;
char letters[5] = "Hello";
char encoded[5];
for (int letter = 0; letter < numOfLetters; ++letter) {
encoded[letter] = encodeLetter(letters[letter]);
}
printf("%s", encoded);
return 0;
}
PS.: if ist eine Verzweigung, keinesfalls eine Schleife.
Ok ersten Fehler hab ich jetzt schon entdeckt: Ich muss bei encodeletter return 0 machen sobald es keiner Bedingung entspricht, ansonsten hab ich eine falsche Berechnung. Allerdings wie soll jetzt der Key neu berechnet werden??
So beim ersten Drüberfliegen:
- Du setzt die Variable key immer erst auf 0, wenn du den Schlüssel berechnest.
- Wieso hast du denn getShiftedLetter wieder aufgedröselt? Der Vorgang für Klein- / Großbuchstaben ändert sich doch nicht, bis auf die Grenzen.
Weil ich folgende Funktion implementieren muss:
unsigned int cipher(char* cipher_str, int start_key)
Folglich muss durch die main(void) der string und der key durchgegeben werden, da nur diese Funktion in der main(void) aufgerufen wird. Also kann ich keine anderen Funktionen in der main(void) aufrufen, somit muss ich alles was weitergegeben werden soll durch meine unsigned int cipher(char* cipher_str, int start_key) weitergeben.
Hmm hab den Key jetzt mal außerhalb definiert. Der Key wird noch immer falsch berechnet :/
Achja und bei return(getshifted) kommt es bei clang zu einem error (darf nur clang verwenden)
Vermutlich wegen dem fehlenden expliziten Typecast von int zu char. Du kannst den Rückgabetyp der Methode zu int oder gleich unsigned int ändern.
Ach sorry, ich war jetzt so faul und habe den char-Pointer einfach als char gewertet, nicht als String. Die Lösung wäre hierfür, die Schleife von main einfach in die Methode zu schieben. Der derzeitige Inhalt kommt in den Schleifenkörper und vor der Schleife legst du ein Array an. Die return-Befehle werden zu Zuweisungen (das aktuell kodierte Zeichen kommt in das Array), danach folgt ein continue, um den nächsten Schleifendurchlauf sofort zu starten.
Ich verstehe dann nur nicht, was die Rückgabe (unsigned int) beinhalten soll.
Vielleicht initialisierst du den Key nicht oder gibst ihn nicht mit hinein?
int key = 0;
for (i = 0; i <= elements; i++) {
// ...
key = calculateKey(cipher_str[i], start_key, key);
// ...
}
Und die calculateKey-Funktion für deinen Fall:
int calculateKey(char letter, int start_Key, int key)
{
key = key == 0 ? start_Key : (toupper(letter) - 65) % key;
key %= 26;
return key;
}
Was du in der Schleife davor machst und wieso du cntChars brauchst, erschließt sich mir übrigens nicht.
Ja genau dasselbe hab ich mir auch schon gedacht aber es funktioniert einfach nicht :/ wenn ich einen String (G , G ,G ,G) mit Schlüssel 50 habe, dann sollte E , N , G, E herauskommen. Es kommt aber E, M , G , E heraus. dh. beim berechnen des neuen Keys geht mir irgendwo eine 1 ab ich weiß nur nicht wo :/
Rückgabe soll die Anzahl der geänderten Zeichen sein, und die Elemente im Ausgangs String sollten ausgetausch werden
Da hast du dich wohl verrechnet?
L = 71 ('G')
SK = 50
K = 0
K = K == 0 ? SK : (L - 65) % K; // = 50
K %= 26; // = 24
D = (K % 2 == 0) ? K : -K; // +K
SH = L + D; // 71 + 24 = 95 - 90 = 5 = 'E'
................
L = 71 ('G')
SK = 50
K = 24
K = K == 0 ? SK : (L - 65) % K; // = (71 - 65) % 24 = 6 % 24 = 6
K %= 26; // = 6
D = (K % 2 == 0) ? K : -K; // +K
SH = L + D; // 71 + 6 = 77 = 'M'
Wart mal:
angenommen Key = 50, und String besteht aus lauter Gs
Zahlenwert von G = 7
7/50 = 0 -> Rest 7
also muss ich 7 Buchstaben weiter nach links -> aus G wird Z
hab mich zuerst vertan es sollte anstatt M eigentlich Z herauskommen
Das wäre jetzt mein aktueller Code: (jetzt gibt er auch Sonderzeichen aus, nur berechnet er den Key falsch weil es immer 1 zu wenig ist. Würde ich den aber im Nachhinein hinzu addieren kommt es natürlich wieder zum Overflow bzw Underflow
#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>
int calculateKey(char letter, int key, int start_key)
{
key = key == 0 ? start_key : (toupper(letter) - 65) % key;
key %= 26;
return key;
}
char cntelements(char* element_str)
{
int elements;
for(elements = 0; element_str[elements] != '\0'; ++elements)
{
elements = elements + 1;
}
return elements;
}
char encodeLetter(char letter, int key)
{
int shiftDirection = (key % 2 == 0) ? key : -key;
int shifted = letter + shiftDirection;
int letter_param;
if (letter > 96 && letter < 123)
{
if (shifted < 97)
{
letter_param = 122 - (97 - shifted) + 1;
}
if (shifted > 122)
{
letter_param = 97 + (shifted - 122) - 1;
}
else
{
letter_param = shifted;
}
return letter_param;
}
if (letter > 64 && letter < 91)
{
if (shifted < 65)
{
letter_param = 90 - (65 - shifted) + 1;
}
if (shifted > 90)
{
letter_param = 65 + (shifted - 90) - 1;
}
else
{
letter_param = shifted;
}
return letter_param;
}
return letter;
}
unsigned int cipher(char* cipher_str, int start_key)
{
int cntChars = 0;
int elements = cntelements(cipher_str);
int i;
int key = 0;
for(i = 0; i <= elements; i++)
{
if((cipher_str[i] < 91 && cipher_str[i] > 64) ||
(cipher_str[i] < 123 && cipher_str[i] > 96))
{
cntChars++;
}
key = calculateKey(cipher_str[i], key, start_key);
printf("%d\n", key);
cipher_str[i] = encodeLetter(cipher_str[i], key);
}
return cntChars;
}
Ja, ich verstehe dein Problem. Du berechnest die Anzahl an Buchstaben von A bis G (beide inklusive). Das sind 7. Ich hingegen rechne die Differenz vom A aus (also exklusive A), welches im ASCII-Code bei der 65 liegt (das G bei 71). Die Differenz ist hier 6.
Richtig und deshalb wandere ich in die falsche Richtung. Aber wenn ich anstatt 65 64 abziehe bekomm ich natürlich den Overflow
Prüfe mal, ob die Rechnung so passen würde:
key = key == 0 ? start_key : (toupper(letter + 1) - 65) % key;
Rechnung würde so passen, aber so kommts wieder zum Overflow
Man müsste halt bevor der Key%2 == 0 Befehl ausgeführt wird, müsste man den Key von 6 auf 7 anheben, damit es wieder passt und danach müsste man den Key wieder um 1 verringern sobald er hinzugezählt wird. Allerdings hab ich da dann wieder das Problem, dass ich um 1 zu wenig addiere bzw subtrahiere
Nein, zusätzlich zu der Addition müsstest du diesen Logikfehler fixen:
if (shifted < 65) {
letter_param = 90 - (65 - shifted) + 1;
}
// FEHLER
if (shifted > 90) {
letter_param = 65 + (shifted - 90) - 1;
}
else {
letter_param = shifted;
}
Der Wert wird nämlich richtig berechnet, aber danach wird nochmal geprüft, ob shifted über 90 liegt. Das tut er nicht, daher steigt der Programmfluss in den else-Fall hinein und überschreibt den vorherig richtig berechneten Wert. Es müsste zu einem großem if-else if-else werden. Für Kleinbuchstaben sieht es genauso aus.
Hättest du von Anfang an meine Implementation von getShiftedLetter verwendet... 😜
Es wird ja schon vorher falsch geprüft. Und zwar hier
int shiftDirection = (key % 2 == 0) ? key : -key;
Hierbei wird anstatt des Key 7 auf Key 6 überprüft -> somit erhalte ich schon da ein falsches Ergebnis. Ich hab halt keine Ahnung wie man das fixen soll :/
Ahh ok jetzt versteh ich es. Das hab ich garnicht gewusst, dass er dann trotzdem in die nächste Schleife springt, aber gut zu wissen, das wär bei einer Prüfung und allgemein beim Coden fatal. Danke für deine Geduld, bin nicht der hellste was programmieren betrifft :)
Nochmals: Verzweigungen (if, if-else, switch, ...) sind keine Schleifen. Schleifen können sich selbst wiederholen, Verzweigungen nicht. 😉
(...) bin nicht der hellste was programmieren betrifft :)
Das habe ich wirklich in keinem Moment gemerkt.
War das Sarkasmus? :D Hmmm aber laut Uni Testscript funktioniert der Code immer noch nicht :/
Nein. Du hast selbst über Lösungen nachgedacht und hinterfragt. Syntaxfehler hast du glaube ich nicht gemacht, wir haben nur über Logikprobleme geschrieben. Das verwerte ich soweit als positiv.
Hmm der Schlüssel wird manchmal trotzdem falsch berechnet
Beispiel:
String: jaekbvuaroirqnmyrtbvwrtzqflopx
Key: 27
herauskommen soll:
ikdkaxuzqohiqmaldzdvvulbqeroon
herauskommen tut:
irejlxuzrgbtqmzyqcyuwqcwselndb
Da stimmen also zwei sachen nicht:
Zuerst ist der Key 27 dann wird er zu 9 obwohl er zu 10 werden sollte und dann wird auch noch nach rechts verschoben obwohl nach links verschoben werden sollte. Der Fehler passiert bei der Übermittelung von der Variable letter in die Funktion calculateKey. Dabei wird für j der Wert 105 weitergegeben also eigentlich i und nicht 106 wie es sein sollte. Musste übrigens noch diese Zeile ändern
key = calculateKey(cipher_str[i], key, start_key);
zu dieser Zeile:
key = calculateKey(cipher_str[i-1], key, start_key);
damit auch immer der Wert von der vorhergehenden Ziffer genommen wird. Allerdings soll das bei "j" ja 106 sein, er nimmt aber 105.
Irgendwelche Ideen?
Aktueller Code sieht so aus:
#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>
int calculateKey(char letter, int key, int start_key)
{
key = key == 0 ? start_key : (toupper(letter) - 64) % key;
return key;
}
char cntelements(char* element_str)
{
int elements;
for(elements = 0; element_str[elements] != '\0'; ++elements)
{
elements = elements + 1;
}
return elements;
}
char encodeLetter(char letter, int key)
{
int shiftDirection = (key % 2 == 0) ? key : -key;
shiftDirection %= 26;
int shifted = letter + shiftDirection;
if (letter > 96 && letter < 123)
{
if (shifted < 97)
{
letter = 123 - (97 - shifted);
}
else if (shifted > 122)
{
letter = 96 + (shifted - 122);
}
else
{
letter = shifted;
}
}
if (letter > 64 && letter < 91)
{
if (shifted < 65)
{
letter = 91 - (65 - shifted);
}
else if (shifted > 90)
{
letter = 64 + (shifted - 90);
}
else
{
letter = shifted;
}
}
return letter;
}
unsigned int cipher(char* cipher_str, int start_key)
{
int cntChars = 0;
int elements = cntelements(cipher_str);
int i;
int key = 0;
for(i = 0; i <= elements; i++)
{
if((cipher_str[i] < 91 && cipher_str[i] > 64) ||
(cipher_str[i] < 123 && cipher_str[i] > 96))
{
cntChars++;
}
key = calculateKey(cipher_str[i-1], key, start_key);
cipher_str[i] = encodeLetter(cipher_str[i], key);
}
return cntChars;
}
int main()
{
char testDaten [] = {"jaekbvuaroirqnmyrtbvwrtzqflopx"};
unsigned int cntelements = cipher( testDaten, 27 );
printf( "Anzahl Elemente %u\n", cntelements );
printf("%s", testDaten);
return 0;
}
also
int shiftDirection = (key % 2 == 0) ? key : -key;
shiftDirection = shiftDirection % 26;
verstehe ich nicht , egal ob key positiv oder negativ ist es kommt immer ein positiver wert raus , also kann sich das doch nie anders verhalten ergo die direction ist immer die gleiche . kann ich das ganze (key % 2 == 0) ? key : -key; doch weg lassen . oder
int shiftDirection = (key % 2 == 0) ? key % 26 : - (key % 26);
ich bräuchte zu dem ganzen das verfahren was angewendet werden soll . so einiges verwundert mich .
Hab das jetzt so gemacht, verändert leider nichts an dem Problem. Wie gesagt an der anderen Funktion wird nichts falsch berechnet. Es bekommt einfach von Anfang an schon einen falschen Wert geliefert. Sprich für j würde 105 weitergegeben werden. Bei dem Beispiel mit string (j,a) will ich dass bei i = 0 nichts weitergegeben wird (eigentlich wärs egal, aber ist halt effizienter) und bei i = 1 will ich, dass j weitergegeben wird, deshalb klappt das mit der Änderung von i in der Schleife auf 1 nicht
Aktuell bin ich hier: Das hat wieder ein paar Fehler ausgemerzt (habe die keycalculator funktion in der schleife unter die verschlüsselungs funktion gesetzt)
#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>
int calculateKey(char letter, int key, int start_key)
{
key = key == 0 ? start_key : (toupper(letter) - 64) % key;
return key;
}
char cntelements(char* element_str)
{
int elements;
for(elements = 0; element_str[elements] != '\0'; ++elements)
{
elements = elements + 1;
}
return elements;
}
char encodeLetter(char letter, int key)
{
int shiftDirection = (key % 2 == 0) ? key % 26 : - (key % 26);
int shifted = letter + shiftDirection;
if (letter > 96 && letter < 123)
{
if (shifted < 97)
{
letter = 123 - (97 - shifted);
}
else if (shifted > 122)
{
letter = 96 + (shifted - 122);
}
else
{
letter = shifted;
}
}
if (letter > 64 && letter < 91)
{
if (shifted < 65)
{
letter = 91 - (65 - shifted);
}
else if (shifted > 90)
{
letter = 64 + (shifted - 90);
}
else
{
letter = shifted;
}
}
return letter;
}
unsigned int cipher(char* cipher_str, int start_key)
{
int cntChars = 0;
int elements = cntelements(cipher_str);
int i,j;
int key = start_key;
for(i = 0; i <= elements; i++)
{
if((cipher_str[i] < 91 && cipher_str[i] > 64) ||
(cipher_str[i] < 123 && cipher_str[i] > 96))
{
cntChars++;
}
j = cipher_str[i];
cipher_str[i] = encodeLetter(cipher_str[i], key);
key = calculateKey(j, key, start_key);
}
return cntChars;
}
int main()
{
return 0;
}
Habe jetzt folgendes Problem und damit hoffentlich letztes Problem:
Wenn zwischen zwei Buchstaben ein Sonderzeichen ist wird mir das für die key berechnung mitberechnet. Ich will die Sonderzeichen aber ignorieren und für die berechnung des keys den letzten buchstaben hernehmen der verändert wurde. (kennt man sich aus was ich mein? :D)
Hier ein Beispiel:
Soll verändert werden: PASDF##NTQIEVM!!'CNT@RBUQVM[
Soll herauskommen: JQRDZ##TVQCVQO!!'BNN@RVWPVG[
Herauskomen tut: JQRDZ##JVQCVQO!!'HKV@LTWPVG[
Tja das Problem wie man sieht ist, dass sobald ein Sonderzeichen übersprungen wird und ausgegeben wird, wird bei der Key-Berechnung natürlich trotzdem das vorherige Element berechnet -> sprich für J wird die Raute und nicht das Z als Berechnungsgrundlage weitergegeben. Wie kann das nun machen, dass man die Sonderzeichen ignoriert? Mit meiner Schleife stoße ich da glaube ich an die Grenzen.
Ok habs geschafft, jetzt funktioniert alles -> thema ist also closed ^^
Gesetzt dem Fall, key ist 3.
key % 2 == 1 > -3
-3 % 26 = -3
Die Richtung bleibt erhalten.
Danke an alle die geholfen haben, alleine wär ich sicherlich nicht draufgekommen :)
So zu rechnen, wäre ausdrücklich falsch gewesen. In der Aufgabenstellung wird es korrekt vorgerechnet:
(z.B. beim Schlüssel 2 wird aus einem A ein C). Ist der Schlüssel ungerade, so erfolgt eine Verschiebung nach links (z.B. beim Schlüssel 3 wird aus einem D ein A).
65(A) + 2 = 67(C)
D(68) - 3 = 65(A)
Vielleicht postest du noch deine endgültige Lösung, falls einmal jemand suchend über diesen Thread stolpern sollte.
Mach ich dann noch, aber erst so gegen Mitternacht (da ist nämlich Abgabe und ich weiß, dass einige von meiner Uni auf gutefrage sind und wenn es wer kopieren würde dann bin ich am ar***) :)
Das wäre die Lösung (wer es jetzt noch findet der hat es verdient zu kopieren :D)
#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>
//
//-----------------------------------------------------------------------------
///
/// Function calculateKey
///
/// @param letter ASCII value of the selected string-element
/// @param key control variable for key
/// @param start_key initial value of key
///
/// @return int key
//
int calculateKey(int letter, int key, int start_key)
{
key = key == 0 ? start_key : (toupper(letter) - 64) % key;
return key;
}
//
//-----------------------------------------------------------------------------
///
/// Function cntelements
///
/// @param element_str string to be checked, counts the elements of the string
///
/// @return int key
//
char cntelements(char* element_str)
{
int elements;
for(elements = 0; element_str[elements] != '\0'; ++elements)
{
continue;
}
return elements;
}
//
//-----------------------------------------------------------------------------
///
/// Function encryptLetter
///
/// @param letter ASCII value of the selected string-element
/// @param key control variable for key
///
/// @return int letter
//
char encryptLetter(int letter, int key)
{
int shiftDirection = (key % 2 == 0) ? key % 26 : - (key % 26);
int shifted = letter + shiftDirection;
if (letter > 96 && letter < 123)
{
if (shifted < 97)
{
letter = 123 - (97 - shifted);
}
else if (shifted > 122)
{
letter = 96 + (shifted - 122);
}
else
{
letter = shifted;
}
}
if (letter > 64 && letter < 91)
{
if (shifted < 65)
{
letter = 91 - (65 - shifted);
}
else if (shifted > 90)
{
letter = 64 + (shifted - 90);
}
else
{
letter = shifted;
}
}
return letter;
}
//
//-----------------------------------------------------------------------------
///
/// Function cipher
///
/// @param *cipher_str string to be checked
/// @param start_key initial key
///
/// @return unsigned int cntChars
//
unsigned int cipher(char* cipher_str, int start_key)
{
unsigned int cntChars = 0;
int elements = cntelements(cipher_str);
int i;
int ascii_value;
int key = start_key;
for(i = 0; i <= elements; i++)
{
if((cipher_str[i] < 91 && cipher_str[i] > 64) ||
(cipher_str[i] < 123 && cipher_str[i] > 96))
{
cntChars++;
ascii_value = cipher_str[i];
cipher_str[i] = encryptLetter(cipher_str[i], key);
key = calculateKey(ascii_value, key, start_key);
}
}
return cntChars;
}
int main()
{
return 0;
}
Danke erstmal für deine ausführliche Antwort. Das Problem ist, dass die Funktion genauso aussehen muss: unsigned int cipher(char* cipher_str, int start_key)
Werde mich mal drannmachen deinen code umzuschreiben, dass es formal wieder passt :) deine Idee ist nämlich schonmal um Welten besser als die meine
Einen sonderlich großen Aufwand sehe ich hierbei erst einmal nicht. Es ändert sich halt nur der Funktionskopf von encodeLetter und der Startschlüssel wird stets durchgereicht.
Das wär mein Code bisher:
-------------------------------------------------------------------------------------------------------------------------------
unsigned int cipher(char* cipher_str, int start_key)
{
int cntChars = 0;
int divisor_rest = 2;
int value_key;
int rest;
int i;
int j;
int key = start_key;
for(i = 0; cipher_str[i] != '\0'; ++i)
i = i + 1;
for(j = 0; j <= i; j++)
{
if(start_key < 1)
{
break;
}
if((cipher_str[j] < 91 && cipher_str[j] > 64) ||
(cipher_str[j] < 123 && cipher_str[j] > 96))
{
cntChars++;
if(cipher_str[j] < 91 && cipher_str[j] > 64)
{
value_key = cipher_str[j] - 64;
rest = key%divisor_rest;
if(rest == 0)
{
cipher_str[j] = cipher_str[j] + key;
}
else if(rest != 0)
{
cipher_str[j] = cipher_str[j] - key;
}
if(cipher_str[j] > 90)
{
cipher_str[j] = cipher_str[j] - 90;
cipher_str[j] = 64 + cipher_str[j];
}
else if(cipher_str[j] < 65)
{
cipher_str[j] = 65 - cipher_str[j];
cipher_str[j] = 91 - cipher_str[j];
}
if(key != 0)
{
key = value_key%key;
}
else if(key < 1)
{
key = start_key;
}
}
if(cipher_str[j] < 123 && cipher_str[j] > 96)
{
value_key = cipher_str[j] - 96;
rest = key%divisor_rest;
if(rest == 0)
{
cipher_str[j] = cipher_str[j] + key;
}
else if(rest != 0)
{
cipher_str[j] = cipher_str[j] - key;
}
if(cipher_str[j] < 97)
{
cipher_str[j] = 97 - cipher_str[j];
cipher_str[j] = 123 - cipher_str[j];
}
else if(cipher_str[j] > 122)
{
cipher_str[j] = cipher_str[j] - 122;
cipher_str[j] = 96 + cipher_str[j];
}
if(key != 0)
{
key = value_key%key;
}
else if(key < 1)
{
key = start_key;
}
}
}
}
return cntChars;
}
Ohne Beispielcode kann ich nicht konkret helfen. Ich würde es aber jedenfalls mit if-Abfragen und modulo fixen.
Frag am Besten deinen TU-Graz Tutor, dafür ist er ja da^^
Achso, der Code steht ja darunter, dann melde ich mich noch mal.
Du machst es ziemlich kompliziert.
Wenn die Substraktion vom Character und dem Key kleiner als 0 ist, kannst du ja folgendes subtrahieren...
*Wert für z* + ((character_value - key) % 26)
Wenn größer als 0, kannst du folgendes addieren...
*Wert für a* + ((character_value + key) % 26)
So gehst du sicher, dass für jeden "Overflow bzw. Underflow" der richtige Wert herauskommt. Das musst du natürlich mit if-Abfragen implementieren.
Und du solltest mehrere Funktionen bilden, der Übersicht halber. Bitte auch den Coding-Standard beachten.
Falls das nicht des Rätsels Lösung ist, melde dich ruhig wieder^^
Informatik 1stes ;-) Ist aber eher Zweitstudium. Mit ESP muss ich mich dennoch rumschlagen.
Wow und da bist du schon so gut drauf in C? Also ich bin ja kompletter Anfänger in C und tu mich da echt nicht so leicht. Respekt! (hast mir ja übrigens gestern mit Analysis auch schon geholfen ;D)
Naja, hab halt schon Programmiererfahrung in C++ und Matlab. Kann aber absolut verstehen, dass ESP für Leute ohne Erfahrung ein Monster ist xD
hast mir ja übrigens gestern mit Analysis auch schon geholfen ;D
Gerne ;-) Bin Mathestudent im 3. Semester, drum beantworte ich hier gerne Analysis-Aufgaben
Hätte das jetzt wie folgt umgeschrieben aber leider funktionierts nicht richtig :/ Irgend eine Idee wo der Fehler stecken könnte?