我在C中实现了一个Vigenere密码。我的解决方案不正确地加密了纯文本。因此我决定对我的代码做一些(有点武断的)改变。更改的目的只是为了使代码更具可读性,方法是更好地定位我的变量,并为它们提供更合适的名称。但是,这种变化现在已经使解决方案正确地加密; 我无法解释为什么当前解决方案适用于原始解决方案 。有人可能会启发我吗?
original.c
//...code to validate user input
string k = argv[1]; //'argv' being a main method parameter
string str = GetString();
//Encrypt using vigenere
for (int i = 0, n = strlen(str); i < n; i++) {
/*An int to keep track of which char to use from the keyword.
Only increment if str[i] was alphabetic.*/
int k_index = 0;
int k_len = strlen(k);
char letter_key = tolower(k[k_index % k_len]);
//Checking if str[i] is alphabetic
if (isalpha(str[i])) {
//Checking if str[i] is uppercase
if (isupper(str[i])) {
//enciphering using vigenere formula
str[i] = ((str[i] - 'A') + (letter_key - 'a')) % 26 + 'A';
printf("%c", str[i]);
k_index++;
}
//If not uppercase, it must be lowercase
else {
//enciphering using vigenere formula
str[i] = ((str[i] - 'a') + (letter_key - 'a')) % 26 + 'a';
printf("%c", str[i]);
k_index++;
}
} else {
printf("%c", str[i]);
}
}
输出
Key: "chasi"
Input/Result: "my plaintext" ---> "oa rnckpvgzv"
Should be: "of pdikutwfv"
updated.c
//...code to validate user input
string k = argv[1];
string str = GetString();
//Encrypt using vigenere
for (int i = 0, j = 0, n = strlen(str); i < n; i++) {
/*"int j" is to keep track of which char to use from the keyword.
Only increment if str[i] was alphabetic.*/
int k_len = strlen(k);
char letter_key = tolower(k[j % k_len]) - 'a';
//Checking if str[i] is alphabetic
if (isalpha(str[i])) {
//Checking if str[i] is uppercase
if (isupper(str[i])) {
//enciphering using vigenere formula
str[i] = ((str[i] - 'A') + letter_key) % 26 + 'A';
printf("%c", str[i]);
j++;
}
//If not uppercase, it must be lowercase
else {
//enciphering using vigenere formula
str[i] = ((str[i] - 'a') + letter_key) % 26 + 'a';
printf("%c", str[i]);
j++;
}
} else {
printf("%c", str[i]);
}
}
输出:
Key: "chasi"
Input/Result: "my plaintext" ---> "of pdikutwfv" (correct)
答案 0 :(得分:3)
原始代码确实:
int k_index = 0;
每次循环。然后当它:
char letter_key = tolower(k[k_index % k_len]);
它正在使用此0
值,因此letter_key
始终为tolower(k[0])
。它所做的地方k_index++;
没有效果,因为变量在再次使用之前会被归零。所以你只是使用键的第一个字符作为整个键。
在更新的代码中,变量j
取代k_index
。它在循环开始时被初始化为0
,而不是每次循环。所以当你这样做时:
char letter_key = tolower(k[j % k_len]) - 'a';
您正在使用j
的更新值。这恰当地使用了整个密钥。