我一整天都在努力弄清楚我创建的这个加密函数我做错了什么。
该函数通过接收一个关键字然后将其转换为ASCII值然后获取该值并将其格式化为可以使用字母索引eg: A= 0, B= 1, C= 2, etc...
然后转换所有纯文本的方式来工作。同样的方法。之后,它会移动纯文本的字符,然后在循环中添加迭代关键字的关键字中的字符值,直到加密纯文本为止。
它适用于我的所有测试,除了像这样的测试:
Keyword is BaZ
输入
plaintext: BaRFoo
输出:
ciphertext: CaQGoh
但所需的输出是
ciphertext: CaQGon
我使用以下加密函数:
void encipher(char* plainText, char*key)
{
printf("ciphertext: ");
char alphabeticalIndex[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int currentKeyChar = 0;
for(int i = 0, n = strlen(plainText); i < n; i++)
{
// check if the end of they key has been reached, if so then reset it
if(currentKeyChar >= strlen(key)) currentKeyChar = 0;
if(isalpha(plainText[i]) == false) printf("%c", plainText[i]);
if(isupper(plainText[i]))
{
// find the cipher character as an int then add it as the key to captialCharNum
int capitalCipherCharNum = ((int) key[currentKeyChar] - 65);
int capitalCharNum = (((int) plainText[i] - 65) + capitalCipherCharNum) % 26;
printf("%c", toupper(alphabeticalIndex[capitalCharNum]));
}
if(islower(plainText[i]))
{
// same as it was for capitals but in this case its lowercase
int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
int lowerCharNum = (((int) plainText[i] - 97) + lowerCipherCharNum) % 26;
printf("%c", tolower(alphabeticalIndex[lowerCharNum]));
}
currentKeyChar++;
}
printf("\n");
}
答案 0 :(得分:1)
您的错误在这里:
int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
当key[currentKeyChar]
大写 时,lowerCipherCharNum
为否定,导致您的密码值错误。要解决您需要的问题:
int lowerCipherCharNum;
if (islower (key[currentKeyChar]))
lowerCipherCharNum = key[currentKeyChar] - 'a';
else
lowerCipherCharNum = key[currentKeyChar] - 'A';
这将更正您的预期输出。
虽然使用数组索引来解决每个字符串没有任何问题,但使用指针算法可以大大简化代码。 (你还需要删除strlen
不必要的重复调用(或至少通过计算key
的长度而不是每次检查它来最小化。)
使用指针运算如何简化逻辑(以及缩短变量名称因为我不想键入)的示例,您可以执行类似以下操作:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void encipher (const char *plaintext, const char *key)
{
const char *aidx = "abcdefghijklmnopqrstuvwxyz",
*p = plaintext,
*k = key;
printf ("ciphertext: ");
while (*p) {
if (isalpha (*p) == 0) printf ("%c", *p);
if (isupper (*p)) {
/* find the cipher character as an int then add it as the key */
int ccicn = (*k - 'A');
int ccnum = (*p - 'A' + ccicn) % 26;
putchar (toupper (aidx[ccnum]));
}
if (islower (*p)) {
/* same as it was for capitals but in this case its lowercase */
int lcicn = islower (*k) ? *k - 'a' : *k - 'A';
int lcnum = (*p - 'a' + lcicn) % 26;
putchar (aidx[lcnum]);
}
p++;
if (*k) k++;
if (!*k) k = key;
}
putchar ('\n'); /* don't use printf for one-character */
}
int main (int argc, char **argv) {
const char *s = argc > 1 ? argv[1] : "BaRFoo",
*key = argc > 2 ? argv[2] : "BaZ";
encipher (s, key);
return 0;
}
示例使用/输出
$ ./bin/encipher
ciphertext: CaQGon
(注意:评论/* don't use printf for one-character */
)
虽然不是错误,但C的标准编码样式避免使用camelCase
或MixedCase
变量名来支持所有小写,同时保留用于宏和常量的大写名称。这是一个风格问题 - 所以它完全取决于你,但如果不遵循它可能会在某些圈子中产生错误的第一印象。
以下是&#34;编辑过的&#34;你的encipher
函数的版本,在评论中有一些额外的想法,代码间隔更宽一些(当你的眼睛变老时,你可能会更加欣赏)
/* if plainText and key are not modified, pass them as 'const char *' */
void encipher (const char *plainText, const char *key)
{
/* place variables before executed code if you have the option...
* (just increases portability to older compilers (like Win7))
*/
char alphabeticalIndex[26] = "abcdefghijklmnopqrstuvwxyz";
int currentKeyChar = 0;
size_t keylen = strlen (key);
printf ("ciphertext: ");
for (int i = 0, n = strlen (plainText); i < n; i++)
{
// check if the end of they key has been reached, if so then reset it
if (currentKeyChar >= (int)keylen) currentKeyChar = 0;
if (isalpha (plainText[i]) == 0) putchar (plainText[i]);
if (isupper (plainText[i]))
{
// find the cipher character as an int then add it as the key
int capitalCipherCharNum = ((int) key[currentKeyChar] - 65);
int capitalCharNum = (plainText[i] - 65 + capitalCipherCharNum) % 26;
putchar (toupper (alphabeticalIndex[capitalCharNum]));
}
if (islower (plainText[i]))
{
// same as it was for capitals but in this case its lowercase
// int lowerCipherCharNum = ((int) key[currentKeyChar] - 97);
int lowerCipherCharNum;
if (islower (key[currentKeyChar]))
lowerCipherCharNum = key[currentKeyChar] - 'a';
else
lowerCipherCharNum = key[currentKeyChar] - 'A';
int lowerCharNum = (plainText[i] - 97 + lowerCipherCharNum) % 26;
putchar (tolower (alphabeticalIndex[lowerCharNum]));
}
currentKeyChar++;
}
putchar ('\n'); /* don't use printf for one-character */
}
仔细看看,如果您有其他问题,请告诉我。