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 的索引)。