C中简单的凯撒变换
我正在尝试用C创建一个简单的Caesar转换程序,但我似乎无法弄明白。 该程序不断崩溃。 任何帮助将不胜感激。
#include #include #include int main(int arc, const char* argv[]) { int shift = atoi(argv[1]); char message[256]; strcpy(message, argv[2]); int i; for(i = 0; i < strlen(message); i++) { printf("%c", message[i] + shift); } putchar('\n'); return 0; }
您没有正确实施Caesar Cipher。 您的代码包含以下行,这是错误的:
printf("%c", message[i] + shift);
要正确执行此操作,您需要将其转换为函数:
printf("%c", encrypt(message[i], shift));
让我们实现这个function:
char encrypt(char input, int shift) { if (input >= 'a' && input <= 'z') return ((input - 'a' + shift) % 26) + 'a'; if (input >= 'A' && input <= 'Z') return ((input - 'A' + shift) % 26) + 'A'; return input; }
只是为了解释数学在该函数中的作用:
-
input - 'a'
告诉我们输入的字母表中的位置(假设输入是小写字母)。 因此,如果输入为'c'
,那么我们将得到2
回。 如果输入是'z'
,我们得到25
。 -
input - 'a' + shift
让我们获得我们用来做密码的角色的新位置。 请注意,这可能是一个比字母更大的数字(26个字符)。 - 因此,为了解决这个问题,我们使用模运算将该数字绑定在
[0 - 25]
。 - 然后在该角色上添加'a'可以获得我们想要打印的实际角色。
请注意,这只能起作用,因为a
到z
和A
到Z
的字符代码是连续的。
您的程序有三个问题。
-
该程序从
argv[1]
和argv[2]
读取,但它假定程序至少接收2个参数。 如果它没有收到这么多,那么它可能崩溃或做任意事情。 您应该明确检查程序是否至少(或确切地)收到两个命令行参数:if (argc != 3) { fprintf(stdout, "Not enough arguments\n"); exit(1); }
注意:将
arc
重命名为argc
,并且程序名称有一个额外的隐式参数,这就是我们检查的原因。) -
该程序将
argv[2]
复制到固定大小的缓冲区中。 如果消息长度超过255个字符(加上空终止符),则它可能会覆盖内存并导致任意事件发生。 在当前情况下,您可以直接处理argv[2]
的字符而无需将其复制到临时变量:for (i = 0; argv[2][i] != '\0' ; i++) { printf("%c", encrypt(argv[2][i], shift)); }
-
凯撒转变需要在z或Z之后环绕。请参阅sharth的回答 。