我正在通过EDX学习哈佛大学的CS50课程(仅适用于我自己,这不是评分工作)。来自PSET2的我的Vigenere密码给出了错误的输出 - 例如,a
的键和输入都应该产生a
的输出,而是给出t
。但是,我无法确定问题所在。
#import <stdio.h>
#import <cs50.h>
#import <string.h>
#import <ctype.h>
int main(int argc, char *argv[])
{
//Variables
string key;
key = argv[1];
string plainText;
plainText = argv[2];
int i;
int k;
i = 0;
k = 0;
//Encrypt the string
for (i = 0; i < strlen(plainText); i++)
{
if (isalpha(plainText[i]))
{
if (islower(plainText[i]))
{
printf("%c",plainText[i] - 97 + key[k] % 26 + 97);
k++;
}
if (isupper(plainText[i]))
{
printf("%c",plainText[i] - 65 + key[k] % 26 + 65);
k++;
}
}
else
printf("%c",plainText[i]);
}
printf("\n");
}
如果key
数组的值应该表示循环移位值(aA
代表零移位,bB
- 移位1,依此类推)那么编码表达式应如下所示
(plainText[i] - 97 + key[k] - 97) % 26 + 97
当然,在这种情况下你必须独立考虑key[k]
字符的情况(并从97
减去65
或key[k]
),你现在完全忽略了。
好吧,我无法提供完整的答案,因为我也在努力解决这个问题。但是,我从你的代码中注意到的一些事情是你的plainText
是argv[2]
但是应该只有2个参数通过命令行传递(argv[0]
(程序的名称)和argv[1]
(用户键))。对于plainText
,您应该使用cs50库中的GetString()
。
我注意到的另一件事是,尽管你在key[k]
中使用了printf()
,但你并没有在循环中迭代它。我对这部分也有困难。所以,不幸的是我无法确定这一部分。我想你可能需要一个循环遍历键的每个字母,以使a / A = 0和z / Z = 25。
不要忘记你的key[]
字母值从97(小写)或65(大写)开始 - 你需要调整它们以使mod 26
操作有意义。
请记住,mod运算符(%
)的优先级高于加法和减法;您可能需要使用parens将其应用于正确的子表达式。
我没有看过赋值的要求,所以我不确定程序是否应该处理关键字符大写或小写(甚至非alpha)的可能性,如果是这样你需要添加一些处理这种复杂性的逻辑。此外,程序现在的编码方式,如果你的密钥比明文短,你会遇到问题 - 我认为你的代码应该在必要时处理'包装'密钥。