2016-07-14 5 views
0

Я работаю над проблемой шифрования Цезаря для проблемы, но я столкнулся с незначительной проблемой. Всякий раз, когда значение шифрования получает больше ascii из 'z', я хочу, чтобы он возвращался к 'a', но я не могу понять, как это сделать. Вот код:Код шифрования Цезаря не работает должным образом 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]); 
    } 

} 

Это довольно основной код. Любая помощь будет оценена.

P.S. вот пример с ключом 4.

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

Что должно произойти с 'z' и' Z', когда ключ равен 4? –

+2

Добро пожаловать в переполнение стека. Вскоре прочитайте страницу [О программе]. Есть много вопросов о реализации шифрования Цезаря на SO. Большинство из них покажут вам способы решения вашей проблемы. Вы действительно смотрите на них (некоторые из них). Не похоже, что вы пытались решить проблему вообще - вы просто знаете, что у вас это есть. Вы должны показать, что вы пробовали. (Кроме того, в какой-то момент вам придется решить, что делать с цифрами и пунктуацией. На данный момент вы относитесь к ним как к письмам, что, вероятно, не самый лучший выбор.) –

+0

Ознакомиться с этим фрагментом: _http: //ideone.com/QwOl1s_ –

ответ

-1

После добавления k к письму, проверьте, если она выше, чем z. Если это так, просто вычтите количество букв в алфавите, чтобы обернуть его.

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

Чтобы иметь дело с верхним и нижним регистром, вам нужны отдельные тесты в основном цикле.

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

Обратите внимание, что я удалил тест для if (s[i] == ' '). Это не обязательно - все, что не письмо, просто осталось в покое.

+0

, но @Barmar, этот код хорош только в том случае, если я просто хочу сменить маленькие буквы .. что насчет капиталов? –

+0

Возможно, проще будет по модулю 26 после добавления. Ie: s [i] = (s [I] + k)% 26. –

+0

Используйте различные случаи в вашем 'if()' for 'islower (s [i])' и 'isupper (s [i])'. Затем вы можете сравнить с 'z' и' Z'. – Barmar

0

Предполагая, что введенный код не является EBCDIC (который имеет неалфавитные символы между буквенными символами), то буквы латинского алфавита (без акцента a-z) кодируются как непрерывные кодовые точки во всех общих наборах кодов. Вращение алфавита просто, когда вы знаете, как это сделать.

Фундаментально, конвертировать каждую букву в 0..25 смещении из письма a или A (в зависимости от случая), добавьте ключ кодирования, взять результат по модулю 26, и добавить начальную букву (a или A) назад. Обратите внимание, что арифметика имеет место как int, но результат присваивается обратно (возможно, подписанному) char.

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

Пример запуска:

$ ./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?] 
$ 

CS50 library легко доступны в Интернете.

+0

EBCDIC все еще вещь? Но большая часть мира использует символы за пределами букв латинского алфавита (без акцента a-z). – zaph

+0

@zaph: Это зависит от машин, на которых вы работаете. В основном «нет», но мэйнфреймы или системы IBM, связанные с ними, все еще могут использовать EBCDIC. В основном предостережение о том, что значение '' z '-' a'' не гарантируется на уровне 25, хотя это, безусловно, самое общее значение. Это комментарий CMA - код в порядке, если нативный код не является EBCDIC. Я полагаю, я мог бы добавить утверждение типа 'assert ('z' - 'a' == 25);' или статическое утверждение, такое как '_Static_assert ('z' - 'a' == 25, 'Code set does not поддерживать непрерывный алфавит "),' где-то в коде. –