首页 > 解决方案 > 凯撒哈佛 CS50X

问题描述

这是 pset2 的一个非常早期的版本,凯撒。我已经想出了如何加密,但在弄清楚如何将 ASCII 码转换为实际字母时遇到了困难。任何人都可以帮忙吗?

for (i = 0, n = strlen(plain); i < n; i++)
{
    if (isalpha (plain [i]))
    {
        index = (int) plain [i] - 65;
        cypher = ((index + key) % 26) + 65;
    }

}

标签: ccs50caesar-cipher

解决方案


您的代码没有考虑字母表的小写部分。要解决此问题,您可以执行以下操作:

//encrypts in place; I've replaced the magic numbers with their char-literal-based derivations
void encrypt(char *plain, int key)
{
    #define cypher plain[i]
    size_t i, n, index;
    for (i = 0, n = strlen(plain); i < n; i++)
    {
        if (isupper (plain [i]))
        {
            index = plain [i] - 'A';
            cypher = ((index + key) % ('Z'-'A'+1) ) + 'A';
        }else if(islower(plain[i])){
            index = plain [i] - 'a';
            cypher = ((index + key) % ('z'-'a'+1)) + 'a';
        }else 
            cypher=plain[i];
    }
}

或者,如果您将自己限制为 ASCII,则可以通过用简单的字符比较替换基于语言环境的 ctype 宏来加快速度。如果您进一步愿意接受[\]^ _ ascii 中 AZ 和 az 范围之间的字符作为编码源/目标,则可以进一步简化为

void encrypt(char *plain, int key)
{
    #define cypher plain[i]
    size_t i, n, index;
    for (i = 0, n = strlen(plain); i < n; i++)
    {
        if(plain[i] >= 'A' && plain[i] <='z'){
            index = plain [i] - 'A';
            cypher = ((index + key) % ('z'-'A'+1) ) + 'A';
        } else cypher=plain[i];
    }
}

示例用法(任一版本):

int main(int c, char **v)
{
    char s[]="Hello, World!";
    encrypt(s,3);
    puts(s);
    encrypt(s,-3);
    puts(s);
}

样品运行:

$ ./a.out
Khoor, Zruog!
Hello, World!

推荐阅读