2015-11-01 85 views
0

我对Vigenere有点问题,并希望得到一些帮助。CS50 Vigenere - 奇怪的图案

/* 
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于完成后,我的终端所有的信件。

我的结果落得这样看的巴兹:注意

  • 任何
  • nything注
  • ything注
  • ything注
  • 事情注
  • 备注
  • 备注
  • NG注注
  • F注意
  • F注意
  • OTE
  • OTE
  • OTE
  • ├e
  • 电子商务

回答

0

以下工作如预期对ACC例子的代码在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(的A的ASCII代码)结果。因此,cipher[i]将是一个从0到25的字符,它们都是不可打印的控制代码(特别是,空字符/ 0字符被C字符串函数视为字符串结束标记)。

线:

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

具有相同的错误。

另外,在两行中,假设关键字符与您正在加密的消息字符具有相同的大小写。如果情况并非如此,您的加密结果将不正确。为了解决这个问题,我建议将整个密钥转换为主要加密循环之前的所有上(或下)情况之前的

您也可以更进一步,在循环前将键转换为0到25之间的数字。但是,执行此操作后,您将无法在密钥上使用strlen(),因为strlen()会在字符串中查找第一个空(= 0)字符的位置。相反,在转换密钥之前,您必须运行strlen(),并将其结果保存在变量中供以后使用。实际上,这在任何情况下都是非常有用的优化(你也应该这样做)。