2016-07-14 23 views
0

Ich habe an einem Caesar-Chiffre-Problem für ein Problem-Set gearbeitet, aber ich stieß auf ein kleines Problem. Immer wenn der Chiffrewert mehr die Ascii von 'z' bekommt, möchte ich, dass er auf 'a' zurückspringt, aber ich bin nicht in der Lage herauszufinden, wie das geht. Hier ist der Code:Caesar-Chiffre-Code funktioniert nicht richtig C

#include <cs50.h> 
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, string argv[]) 
{ 
    if(argc !=2 && !isdigit(argv[1])) 
    { 
     return 1; 
    } 

    //convert input to int and get the string 
    int k = atoi(argv[1]); 
    k=k%26; 
    //printf("%d" ,k); 
    //get he text 

    char *s; 
    s=GetString(); 
    int i, n=strlen(s); 

    //checking each character 
    for(i=0;i<n;i++) 
    { 
     if(s[i]==' ') 
     { 
      s[i]=' '; 
     } 
     else 
     { 
      s[i]=s[i]+k; 
     } 
     printf("%c" ,s[i]); 
    } 

} 

Dies ist ein recht einfach Code. Jede Hilfe wird geschätzt.

P.S. Hier ist ein Beispiel mit der Taste 4.

input- Vinay Dawani 
output- Zmre} He{erm 
+1

Was soll mit 'z' und' Z' geschehen, wenn der Schlüssel 4 ist? –

+2

Willkommen bei Stack Overflow. Bitte lesen Sie die [Über] Seite bald. Es gibt eine Menge Fragen über Caesar-Chiffre-Implementierungen auf SO. Die meisten von ihnen würden Ihnen Wege aufzeigen, wie Sie Ihr Problem lösen können. Sie sehen sich (einige von ihnen) wirklich an. Es sieht nicht so aus, als hättest du versucht, mit dem Problem fertig zu werden - du weißt nur, dass du es hast. Sie sollten zeigen, was Sie versucht haben. (Außerdem müssen Sie sich irgendwann entscheiden, was mit Ziffern und Interpunktion zu tun ist. Im Moment behandeln Sie sie wie Buchstaben, was wahrscheinlich nicht die beste Wahl ist.) –

+0

Schauen Sie in dieses Snippet: _http: //ideone.com/QwOl1s_ –

Antwort

-1

Nachdem Sie k zu dem Brief hinzufügen, überprüfen Sie, ob es höher als z. Wenn dies der Fall ist, subtrahieren Sie einfach die Anzahl der Buchstaben im Alphabet, um sie zu umbrechen.

s[i] = s[i]+k; 
if (s[i] > 'z') { 
    s[i] = s[i] - 26; 
} 

Um mit Groß- und Kleinschreibung umzugehen, benötigen Sie separate Tests in der Hauptschleife.

for(i=0;i<n;i++) 
{ 
    if(islower(s[i])) 
    { 
     s[i] += k; 
     if (s[i] > 'z') { 
      s[i] -= 26; 
     } 
    } 
    else if (isupper(s[i])) 
    { 
     s[i] += k; 
     if (s[i] > 'Z') { 
      s[i] -= 26; 
     } 
    } 
    printf("%c" ,s[i]); 
} 

Beachten Sie, dass ich den Test für if (s[i] == ' ') entfernt. Das ist nicht nötig - alles, was kein Brief ist, bleibt einfach in Ruhe.

+0

, aber @Barmar, dieser Code ist nur gut, wenn ich nur kleine Buchstaben ändern möchte ... was ist mit Großbuchstaben? –

+0

Vielleicht einfacher wäre es, nach der Zugabe um 26 zu modulo. Ie: s [i] = (s [I] + k)% 26. –

+0

Verwenden Sie verschiedene Fälle in Ihrem 'if()' für 'islower (s [i])' und 'isupper (s [i])'. Dann können Sie mit 'Z' und' Z' vergleichen. – Barmar

0

Unter der Annahme, dass der verwendete Code nicht ist (mit nicht alphabetischen Zeichen zwischen alphabetischen Zeichen), werden Buchstaben des lateinischen Alphabets (unbetont a-z) als zusammenhängende Codepunkte in allen gängigen Codesätzen codiert. Die Rotation des Alphabets ist einfach, wenn Sie wissen, wie.

Grundsätzlich konvertieren Sie jeden Buchstaben in einem Offset-0..25 aus dem Brief a oder A (auf Fall abhängig), die Verschlüsselungsschlüssel hinzufügen, nehmen Sie das Ergebnis Modulo 26, und fügen Sie den Anfangsbuchstaben (a oder A) zurück. Beachten Sie, dass die Arithmetik als int stattfindet, aber das Ergebnis wird einem (möglicherweise signierten) char zugewiesen.

#include <cs50.h> 
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, string argv[]) 
{ 
    if (argc != 2 || !isdigit((unsigned char)argv[1][0])) 
    { 
     fprintf(stderr, "Usage: %s shift\n", argv[0]); 
     return 1; 
    } 

    // convert input to int and get the string 
    int k = atoi(argv[1]) % 26; 
    if (k < 0) 
     k += 26; 

    char *s = GetString(); 
    int n = strlen(s); 

    printf("Original: [%s]\n", s); 

    // encoding each character 
    for (int i = 0; i < n; i++) 
    { 
     if (isupper((unsigned char)s[i])) 
     { 
      s[i] = 'A' + (s[i] - 'A' + k) % 26; 
     } 
     else if (islower((unsigned char)s[i])) 
     { 
      s[i] = 'a' + (s[i] - 'a' + k) % 26; 
     } 
    } 

    printf("Encrypted: [%s]\n", s); 
    return 0; 
} 

Beispiel Lauf:

$ ./caesar13 3 
Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it? 
Original: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?] 
Encrypted: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?] 
$ ./caesar50 23 
Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw? 
Original: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?] 
Encrypted: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?] 
$ 

Die CS50 library ist leicht zugänglich online.

+0

EBCDIC ist immer noch eine Sache? Aber der größte Teil der Welt verwendet Zeichen außerhalb der Buchstaben des lateinischen Alphabets (nicht akzentuiert a-z). – zaph

+0

@zaph: Das hängt von den Maschinen ab, an denen Sie arbeiten. Meist "Nein", aber IBM Mainframes oder damit verbundene Systeme können immer noch EBCDIC verwenden. Es ist hauptsächlich eine Warnung, dass der Wert von "z" - "a" nicht garantiert 25 ist, obwohl es bei weitem der gebräuchlichste Wert ist. Es ist ein CMA-Kommentar - der Code ist OK, vorausgesetzt, der native Code ist nicht EBCDIC. Ich nehme an, ich könnte eine Assertion hinzufügen, wie zum Beispiel 'assert ('z' - 'a' == 25);' oder eine statische Assertion wie '_Static_assert ('z' - 'a' == 25," Code set "nicht unterstütze zusammenhängendes Alphabet ");' irgendwo im Code. –