C Programmcode Ceasar Cipher?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

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.


Maximum12345 
Beitragsersteller
 09.11.2019, 11:04

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

0
regex9  09.11.2019, 15:17
@Maximum12345

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.

0
Maximum12345 
Beitragsersteller
 09.11.2019, 14:54

Hätte das jetzt wie folgt umgeschrieben aber leider funktionierts nicht richtig :/ Irgend eine Idee wo der Fehler stecken könnte?

#include <stdio.h>
#include <inttypes.h>
#include <ctype.h>  

int calculateKey(char letter, int start_Key)
{
  int key = 0;
  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;
    }
  }

  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;
}



unsigned int cipher(char* cipher_str, int start_key)
{
 
  int cntChars = 0;
  int elements = cntelements(cipher_str);
  int i;
  int 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++;
    }
    key = calculateKey(cipher_str[i], start_key);
    cipher_str[i] = encodeLetter(cipher_str[i], key);
  }

  return cntChars;
}
0
Maximum12345 
Beitragsersteller
 09.11.2019, 15:13
@Maximum12345

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??

0
regex9  09.11.2019, 15:13
@Maximum12345

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.
0
Maximum12345 
Beitragsersteller
 09.11.2019, 15:22
@regex9

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 :/

0
Maximum12345 
Beitragsersteller
 09.11.2019, 15:30
@Maximum12345

Achja und bei return(getshifted) kommt es bei clang zu einem error (darf nur clang verwenden)

0
regex9  09.11.2019, 15:55
@Maximum12345

Vermutlich wegen dem fehlenden expliziten Typecast von int zu char. Du kannst den Rückgabetyp der Methode zu int oder gleich unsigned int ändern.

1
regex9  09.11.2019, 16:03
@regex9

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.

1
regex9  09.11.2019, 16:11
@Maximum12345

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.

1
Maximum12345 
Beitragsersteller
 09.11.2019, 16:16
@regex9

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 :/

0
Maximum12345 
Beitragsersteller
 09.11.2019, 16:17
@regex9

Rückgabe soll die Anzahl der geänderten Zeichen sein, und die Elemente im Ausgangs String sollten ausgetausch werden

0
regex9  09.11.2019, 16:39
@Maximum12345

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' 
0
Maximum12345 
Beitragsersteller
 09.11.2019, 16:45
@regex9

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

0
Maximum12345 
Beitragsersteller
 09.11.2019, 16:57
@Maximum12345

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;
}


0
regex9  09.11.2019, 17:07
@Maximum12345

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.

1
Maximum12345 
Beitragsersteller
 09.11.2019, 17:07
@regex9

Richtig und deshalb wandere ich in die falsche Richtung. Aber wenn ich anstatt 65 64 abziehe bekomm ich natürlich den Overflow

0
regex9  09.11.2019, 17:11
@Maximum12345

Prüfe mal, ob die Rechnung so passen würde:

key = key == 0 ? start_key : (toupper(letter + 1) - 65) % key;
0
Maximum12345 
Beitragsersteller
 09.11.2019, 17:16
@regex9

Rechnung würde so passen, aber so kommts wieder zum Overflow

0
Maximum12345 
Beitragsersteller
 09.11.2019, 17:17
@regex9

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

0
regex9  09.11.2019, 17:35
@Maximum12345

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... 😜

1
Maximum12345 
Beitragsersteller
 09.11.2019, 17:51
@regex9

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 :/

0
Maximum12345 
Beitragsersteller
 09.11.2019, 18:39
@regex9

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 :)

0
regex9  09.11.2019, 18:58
@Maximum12345

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.

1
Maximum12345 
Beitragsersteller
 09.11.2019, 19:00
@regex9

War das Sarkasmus? :D Hmmm aber laut Uni Testscript funktioniert der Code immer noch nicht :/

0
regex9  09.11.2019, 19:05
@Maximum12345

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.

1
Maximum12345 
Beitragsersteller
 09.11.2019, 22:18
@regex9

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?

0
Maximum12345 
Beitragsersteller
 09.11.2019, 22:49
@regex9

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;
}


0
RakonDark  10.11.2019, 06:39
@Maximum12345

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);

1
RakonDark  10.11.2019, 07:41
@RakonDark

ich bräuchte zu dem ganzen das verfahren was angewendet werden soll . so einiges verwundert mich .

1
RakonDark  10.11.2019, 07:45
@RakonDark

ups hab ich übersehen das du das oben beschrieben hast lol .

1
Maximum12345 
Beitragsersteller
 10.11.2019, 10:34
@RakonDark

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

0
Maximum12345 
Beitragsersteller
 10.11.2019, 11:05
@RakonDark

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;
}




0
Maximum12345 
Beitragsersteller
 10.11.2019, 11:18
@Maximum12345

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.

0
Maximum12345 
Beitragsersteller
 10.11.2019, 11:54
@Maximum12345

Ok habs geschafft, jetzt funktioniert alles -> thema ist also closed ^^

1
Maximum12345 
Beitragsersteller
 10.11.2019, 15:05
@regex9

Danke an alle die geholfen haben, alleine wär ich sicherlich nicht draufgekommen :)

0
regex9  10.11.2019, 15:05
@regex9

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)
1
regex9  10.11.2019, 15:06
@Maximum12345

Vielleicht postest du noch deine endgültige Lösung, falls einmal jemand suchend über diesen Thread stolpern sollte.

1
Maximum12345 
Beitragsersteller
 10.11.2019, 15:10
@regex9

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***) :)

1
Maximum12345 
Beitragsersteller
 10.11.2019, 19:38
@regex9

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;
}


0

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.

Woher ich das weiß:Studium / Ausbildung – Mathematik-Studium

Maximum12345 
Beitragsersteller
 08.11.2019, 22:38

Welches Semester wenn ich fragen darf? :D

0
Quotenbanane  08.11.2019, 22:58
@Maximum12345

Informatik 1stes ;-) Ist aber eher Zweitstudium. Mit ESP muss ich mich dennoch rumschlagen.

1
Maximum12345 
Beitragsersteller
 08.11.2019, 23:00
@Quotenbanane

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)

1
Quotenbanane  08.11.2019, 23:06
@Maximum12345

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

1
Quotenbanane  08.11.2019, 22:56

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.

1