2015-11-01 3 views
0

У меня проблема с Vigenere и мне нужна помощь.CS50 Vigenere - Strange pattern

/* 
This program is a Vigenere Cipher. 
I am Daniel of Asguard. 
*/ 

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

int main(int argc, string argv[]) 
{ 
string cipher; //this is a placeholder for the ciphered message. 
char * key = argv[1]; 
int i = 0; 


if (argc != 2) //this is meant to trigger if you don't enter the right call. So 
{ 
    printf("Please enter the cipher key when you call the program, such as './CaesarCipher 7'.\n"); // 
    return 1; 
} 

if (!isalpha(key[i])) //this is meant to trigger if you don't enter the right call. So 
{ 
    printf("Please only enter a word, no numerical numbers please."); // 
    return 1; 
} 

do 
{ 
    //printf("Please enter the message you would like to have converted, please. \n"); 
    cipher = GetString(); 
} 
while (cipher == NULL); 

for (int i = 0, k = 0, n = strlen(cipher); i < n; i++, k++) //this is so the code knows to change only the characters in the sting cipher. 
    { 
     if (k >= strlen(key)) 
     { 
      k = 0; 
     } 
      { 
      if (isupper(cipher[i])) 
       { 
        //cipher[i] = 'A' + (((cipher[i] - 'A') + (key[k]) - 'A') % 26); 
        cipher[i] = ((key[k] - 65) + (cipher[i] - 65)) % 26; 
        printf("%s\n", cipher); 
       } 
      else (islower(cipher[i])); 
       { 
        //cipher[i] = 'a' + (((cipher[i] - 'a') + (key[i]) - 'a') % 26); 
        cipher[i] = ((key[k] - 97) + (cipher[i] - 97)) % 26; 
        printf("%s\n", cipher); 
       } 
     } 
    } 
printf("%s\n", cipher); 
return 0; 
} 

Когда я делаю это мои результаты будут получены странные символы: ⎽c▒⎺e┼├⎼▒┤└e⎼ @ ☃de5▮: ·/┬⎺⎼┐⎽⎻▒ce/⎻⎽e├ 2 $ └▒┐e ┴☃ ± e┼e⎼e для всех букв в моем терминале после завершения.

Мои результаты в конечном итоге выглядит, как это для БАЗ:

  • Anything примечания
  • nything примечания
  • ружения примечания
  • ружения примечания
  • вещь Примечание
  • примечание
  • примечание
  • нг Примечания
  • примечания
  • примечания
  • F Примечание
  • F Примечание
  • Примечание
  • ОТ
  • ОТЕ
  • ОТЕ
  • ├e
  • е

ответ

0

ниже код работы, как ожидается, акк к примеру в https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher

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

int main (void) 
{ 
    const char *cipher = "ATTACKATDAWN"; 
    const char *key = "LEMON"; 
    char *newkey; 
    char *p, *q; 
    int i =0; 
    int col, row; 
    if (strlen (key) < strlen (cipher)) 
    { 
printf ("key %s \n", key); 
printf ("cipher \t%s \n", cipher); 
newkey = malloc (strlen (cipher) +1); 
strcpy (newkey, key); 
p = (char *) (newkey + strlen (newkey)) ; 
q = (char *) key; 
i =strlen (key); 
while (i < strlen (cipher)) 
{ 
     i++; 
     if (*q == 0) 
    q = (char *) key; 
     *p = *q; 
     p++; 
     q++; 
} 
    *p = 0; 
    printf ("newk \t%s \n", newkey); 
    } 
    p = (char *) newkey; 
    q= (char *) cipher; 
    int a[1] ; 
    a[1] =0; 
    for (i =0 ; i < strlen(newkey); i++) 
    { 
row = *p -65; 
col = *q -65; 
if (col+row > 26) 
     a [0] = 65 + col+row -26; 
else 
     a [0] = 65 +col+row; 
printf ("%s",(char *) &a[0]); 
p++; 
q++; 
    } 
    printf ("\n"); 
    free(newkey); 
/*L X F O P V E F R N H R*/ 
return 0; 
} 
0

На линии:

cipher[i] = ((key[k] - 65) + (cipher[i] - 65)) % 26; 

вы забыли добавить обратно 65 (ASCII-код A) в результат. Таким образом, cipher[i] будет символом от 0 до 25, все из которых являются непечатаемыми управляющими кодами (а символ null/0, в частности, обрабатывается строковыми функциями C как маркер конца строки).

Линия:

cipher[i] = ((key[k] - 97) + (cipher[i] - 97)) % 26; 

имеет ту же ошибку.

Кроме того, на обеих линиях вы предполагаете, что ключевой символ имеет тот же случай, что и символ сообщения, который вы шифруете. Если это не так, ваши результаты шифрования будут неверными. Чтобы исправить это, я бы предложил преобразовать весь ключ во весь верхний (или нижний) регистр до основной цикл шифрования.

Вы также можете сделать еще один шаг и преобразовать ключ в число от 0 до 25 до цикла. Тем не менее, вы не сможете использовать strlen() по ключу после этого, так как strlen() ищет позицию первого символа null (= 0) в строке. Вместо этого вам нужно будет запустить strlen() перед преобразованием ключа и сохранить его результат в переменной для последующего использования.На самом деле, это было бы полезной оптимизацией в любом случае (и вы тоже должны это сделать для сообщения).