【问题标题】:CS50 Vigenere - Strange patternCS50 Vigenere - 奇怪的图案
【发布时间】:2015-11-01 06:48:48
【问题描述】:

我在使用 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 完成后我终端中的所有字母。

BaZ 的结果最终看起来像这样:

  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • 注意事项
  • f 注意
  • f 注意
  • 注意
  • ├e
  • e

【问题讨论】:

    标签: c encryption vigenere cs50


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      上线:

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

      您忘记在结果中加回 65(A 的 ASCII 码)。因此,cipher[i] 将是一个从 0 到 25 的字符,所有这些都是不可打印的控制代码(特别是 null / 0 字符被 C 字符串函数视为字符串结束标记)。

      行:

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

      有同样的错误。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-18
        相关资源
        最近更新 更多