Print Caesar Shift in C 正在打印输入的 HELLO 文本
Print Caesar Shift in C is printing the entered text of HELLO
我正在尝试对来自用户的文本使用 ascii 字符的模运算执行凯撒密码。但是,我的代码只是打印输入的测试。例如,当输入的文本是 HELLO the program returns "HELLO"。目标是对于 13 的密钥,它应该打印 URYYB。谢谢。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int key = atoi(argv[1]);
string plaintext = get_string("Enter plaintext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
if (isalpha(plaintext[i]))
{
if (isupper(plaintext[i]))
{
printf("%c", ((plaintext[i] + key) % 26) + 65);
}
else if (islower(plaintext[i]))
{
printf("%c", ((plaintext[i] + key) % 26) + 97);
}
else
{
printf("%c", plaintext[i]);
}
}
}
printf("\n");
如果密钥是 13,你的密码函数什么都不做:
运行稍微修改了一下,看看结果:D
int main()
{
int key = 13;
char plaintext[] = "HELLO";
for (int i = 0; i < strlen(plaintext); i++)
{
if (isalpha(plaintext[i]))
{
if (isupper(plaintext[i]))
{
printf("%d, %d\n", (int)plaintext[i], (int)(((plaintext[i] + key) % 26) + 65));
}
else
{
if (islower(plaintext[i]))
{
//printf("%c", ((plaintext[i] + key) % 26) + 97);
}
else
{
//printf("%c", plaintext[i]);
}
}
}
}
printf("\n");
return 0;
}
初步分析
'H'的字符编码为72。
(72 + 13) % 26 + 65 = 85 % 26 + 65 = 7 + 65 ~ 'H'
我们先减去65看看:
(72 - 65 + 13) % 26 + 65 = (7 + 13) % 26 + 65 = 20 % 26 + 65 = 20 + 65 = 85 ~ 'U'
解决方案
printf("%c", ((plaintext[i] + key - 65) % 26) + 65);
和
printf("%c", ((plaintext[i] + key - 97) % 26) + 97);
分别
证明
如果您有一个字符代码 C,其中 S <= C < S + 26,那么您使用的公式是:
((C + 键) % 26) + S
然而,实际的字母是 L 我们知道
C = S + L,
所以公式是
((S + L + 键) % 26) + S
并且,因为
(A + B) % C = ((A % C) + (B % C)) % C,
用 (S) 替换 A,用 (L + key) 替换 B,用 26 替换 C,我们得到:
((S % 26) + ((L + key) % 26)) % 26,我们看到结果被 (S % 26) 扭曲了,在 65 的情况下恰好是 13。由于 13 的失真 + 您在 26 的模 class 中使用的 13 的密钥将产生首字母!
所以,提议的新公式
((C + 键 - S) % 26) + S = (((S + L) + 键 - S) % 26) + S = ((L + 键) % 26) + S
正是您所需要的。
您将 key
添加到每个明文字符的值,而这意味着应用于字母表中相应字母的索引。例如,对于 ASCII 中的 'H'
,您的公式是:(72 + 13) % 26
给出 7
(从零开始时,这也是字母表中 H 的索引)。
在应用键之前,您需要将字符的 (ASCII) 值转换为其索引,例如 ((plaintext[i] - 'A' + key) % (1 + 'Z' - 'A')) + 'A'
。
'H'
的解决方案将变为 (72 - 65 + 13) % 26
,从而给出 20
(正确答案,7 + 13
,U 的索引)。
我正在尝试对来自用户的文本使用 ascii 字符的模运算执行凯撒密码。但是,我的代码只是打印输入的测试。例如,当输入的文本是 HELLO the program returns "HELLO"。目标是对于 13 的密钥,它应该打印 URYYB。谢谢。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int key = atoi(argv[1]);
string plaintext = get_string("Enter plaintext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
if (isalpha(plaintext[i]))
{
if (isupper(plaintext[i]))
{
printf("%c", ((plaintext[i] + key) % 26) + 65);
}
else if (islower(plaintext[i]))
{
printf("%c", ((plaintext[i] + key) % 26) + 97);
}
else
{
printf("%c", plaintext[i]);
}
}
}
printf("\n");
如果密钥是 13,你的密码函数什么都不做:
运行稍微修改了一下,看看结果:D
int main()
{
int key = 13;
char plaintext[] = "HELLO";
for (int i = 0; i < strlen(plaintext); i++)
{
if (isalpha(plaintext[i]))
{
if (isupper(plaintext[i]))
{
printf("%d, %d\n", (int)plaintext[i], (int)(((plaintext[i] + key) % 26) + 65));
}
else
{
if (islower(plaintext[i]))
{
//printf("%c", ((plaintext[i] + key) % 26) + 97);
}
else
{
//printf("%c", plaintext[i]);
}
}
}
}
printf("\n");
return 0;
}
初步分析
'H'的字符编码为72。
(72 + 13) % 26 + 65 = 85 % 26 + 65 = 7 + 65 ~ 'H'
我们先减去65看看:
(72 - 65 + 13) % 26 + 65 = (7 + 13) % 26 + 65 = 20 % 26 + 65 = 20 + 65 = 85 ~ 'U'
解决方案
printf("%c", ((plaintext[i] + key - 65) % 26) + 65);
和
printf("%c", ((plaintext[i] + key - 97) % 26) + 97);
分别
证明
如果您有一个字符代码 C,其中 S <= C < S + 26,那么您使用的公式是:
((C + 键) % 26) + S
然而,实际的字母是 L 我们知道
C = S + L,
所以公式是
((S + L + 键) % 26) + S
并且,因为
(A + B) % C = ((A % C) + (B % C)) % C,
用 (S) 替换 A,用 (L + key) 替换 B,用 26 替换 C,我们得到:
((S % 26) + ((L + key) % 26)) % 26,我们看到结果被 (S % 26) 扭曲了,在 65 的情况下恰好是 13。由于 13 的失真 + 您在 26 的模 class 中使用的 13 的密钥将产生首字母!
所以,提议的新公式
((C + 键 - S) % 26) + S = (((S + L) + 键 - S) % 26) + S = ((L + 键) % 26) + S
正是您所需要的。
您将 key
添加到每个明文字符的值,而这意味着应用于字母表中相应字母的索引。例如,对于 ASCII 中的 'H'
,您的公式是:(72 + 13) % 26
给出 7
(从零开始时,这也是字母表中 H 的索引)。
在应用键之前,您需要将字符的 (ASCII) 值转换为其索引,例如 ((plaintext[i] - 'A' + key) % (1 + 'Z' - 'A')) + 'A'
。
'H'
的解决方案将变为 (72 - 65 + 13) % 26
,从而给出 20
(正确答案,7 + 13
,U 的索引)。