C中的凯撒密码 - 加密和解密
Caesar cipher in C - encryption and decryption
我制作了这个程序,但似乎不起作用,你能告诉我为什么吗?我花了大约 3 个小时才弄清楚为什么它不起作用,但我不知道。我想知道这是否与 shift 无关,但我不确定。这是我制作的第一个程序,对于一些基本错误我深表歉意。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char message[100];
int shift;
int i;
int choice;
printf("Enter operation with message\n");
printf("encrypt - 1\n");
printf("decrypt - 2\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
printf("Enter message to encrypt\n");
scanf("%d", &message);
printf("Enter shift\n");
scanf("%d", &shift);
for (i = 0; message[i] != '[=10=]'; i++)
{
message[i] = message[i] + shift;
if (message[i] > 'z')
message[i] = message[i] - 26;
}
printf("Encrypted message: %s\n", message);
break;
}
case 2:
{
printf("Enter message to decrypt\n");
scanf("%d", &message);
printf("Enter shift\n");
scanf("%d", &shift);
for (i = 0; message[i] != '[=10=]'; i++)
{
message[i] = message[i] - shift;
if (message[i] > 'z')
message[i] = message[i] - 26;
}
printf("Decrypted message: %s\n", message);
break;
}
}
return (EXIT_SUCCESS);
}
这是一个输出屏幕:
始终注意编译器警告。如果我编译您的代码,我会收到以下警告(以及更多警告):
../main.c:21:10: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘char (*)[100]’ [-Wformat=]
scanf("%d", &message);
^
../main.c:38:10: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘char (*)[100]’ [-Wformat=]
scanf("%d", &message);
^
主要有两个问题:
1. scanf()
:
格式说明符错误
了解不同的格式说明符 here on cppreference。
在您使用的代码中:
char message[100];
scanf("%d", &message);
但不是用于 int
的 %d
,对于 C 字符串 (char*
) 应该是 %s
。最好使用 %99s
来避免 string format vulnerability. Further it should be just message
without the ampersand (&
) because the array name will decay 到 char*
,但 &message
将是指向数组的指针:char (*)[100]
。这将导致警告,因为 %s
期望 char*
.
char message[100];
if (1 != scanf("%99s", message)) /* buffer size - 1 */
return EXIT_FAILURE;
此外scanf()
returns 成功读取元素的数量。我建议始终检查指示错误的 return 值。
2。解密逻辑错误:
而不是检查 message[i] > 'z'
,它必须是 message[i] < 'a'
,因为您要减去 shift
值。在这种情况下,进一步加 26 而不是减去它。
for (i = 0; message[i] != '[=13=]'; i++)
{
message[i] = message[i] - shift;
if (message[i] < 'a')
message[i] = message[i] + 26;
}
编辑#1:
您输入的消息还有另一个逻辑问题。您的代码仅适用于由小写字母组成的消息。您可以将其扩展为使用大写字母 to.
此外,您的缓冲区可能包含 signed char
s1,因为它被声明为 char message[100];
,这意味着如果计算:message[i] = message[i] + shift;
overflows the bahaviour is undefined. That would happen for example if you use character z
(decimal 122 in ASCII code) 和 6 的 shift
将导致 128 但 signed char
最多可以容纳 127.
1 我写 "may hold signed char
s" 因为 C 标准将它留给 define wether a char
is signed
or unsigned
的实现,但对于 GCC 和 MSVC,默认情况下 char
将是 signed char
。
我制作了这个程序,但似乎不起作用,你能告诉我为什么吗?我花了大约 3 个小时才弄清楚为什么它不起作用,但我不知道。我想知道这是否与 shift 无关,但我不确定。这是我制作的第一个程序,对于一些基本错误我深表歉意。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char message[100];
int shift;
int i;
int choice;
printf("Enter operation with message\n");
printf("encrypt - 1\n");
printf("decrypt - 2\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
printf("Enter message to encrypt\n");
scanf("%d", &message);
printf("Enter shift\n");
scanf("%d", &shift);
for (i = 0; message[i] != '[=10=]'; i++)
{
message[i] = message[i] + shift;
if (message[i] > 'z')
message[i] = message[i] - 26;
}
printf("Encrypted message: %s\n", message);
break;
}
case 2:
{
printf("Enter message to decrypt\n");
scanf("%d", &message);
printf("Enter shift\n");
scanf("%d", &shift);
for (i = 0; message[i] != '[=10=]'; i++)
{
message[i] = message[i] - shift;
if (message[i] > 'z')
message[i] = message[i] - 26;
}
printf("Decrypted message: %s\n", message);
break;
}
}
return (EXIT_SUCCESS);
}
这是一个输出屏幕:
始终注意编译器警告。如果我编译您的代码,我会收到以下警告(以及更多警告):
../main.c:21:10: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘char (*)[100]’ [-Wformat=] scanf("%d", &message); ^ ../main.c:38:10: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘char (*)[100]’ [-Wformat=] scanf("%d", &message); ^
主要有两个问题:
1. scanf()
:
了解不同的格式说明符 here on cppreference。
在您使用的代码中:
char message[100];
scanf("%d", &message);
但不是用于 int
的 %d
,对于 C 字符串 (char*
) 应该是 %s
。最好使用 %99s
来避免 string format vulnerability. Further it should be just message
without the ampersand (&
) because the array name will decay 到 char*
,但 &message
将是指向数组的指针:char (*)[100]
。这将导致警告,因为 %s
期望 char*
.
char message[100];
if (1 != scanf("%99s", message)) /* buffer size - 1 */
return EXIT_FAILURE;
此外scanf()
returns 成功读取元素的数量。我建议始终检查指示错误的 return 值。
2。解密逻辑错误:
而不是检查 message[i] > 'z'
,它必须是 message[i] < 'a'
,因为您要减去 shift
值。在这种情况下,进一步加 26 而不是减去它。
for (i = 0; message[i] != '[=13=]'; i++)
{
message[i] = message[i] - shift;
if (message[i] < 'a')
message[i] = message[i] + 26;
}
编辑#1:
您输入的消息还有另一个逻辑问题。您的代码仅适用于由小写字母组成的消息。您可以将其扩展为使用大写字母 to.
此外,您的缓冲区可能包含 signed char
s1,因为它被声明为 char message[100];
,这意味着如果计算:message[i] = message[i] + shift;
overflows the bahaviour is undefined. That would happen for example if you use character z
(decimal 122 in ASCII code) 和 6 的 shift
将导致 128 但 signed char
最多可以容纳 127.
1 我写 "may hold signed char
s" 因为 C 标准将它留给 define wether a char
is signed
or unsigned
的实现,但对于 GCC 和 MSVC,默认情况下 char
将是 signed char
。